Как стать автором
Обновить

Комментарии 19

Вечная тема… И без единственного правильного решения

В этом докладе освещается возможное универсальное решение от «всех проблем» с датой.
Насчет потери информации с UTC, чувак немного не прав. Митинг это не просто засечка на временной оси, это комплексный объект с кучей атрибутов. Одним из них является время, другим местоположение.

Время мы храним в UTC. А пользователю показываем согласно актуальной (на момент просмотра!) временной зоне — митинга если offline, или пользователя если online.

Я тоже был немного не прав :) Что пытался донести докладчик, это то что не всякое время можно с ходу перевести до UTC. Вот только пример, на мой взгляд, он привёл некоректный. Потому что для данного случая надо записыват в базу место и локальное время (а не UTC, как написал я выше). То есть никаких временных поясов при сохранении не нужно.

При отображении из сохранённой информации можно легко востановить нужную TZ:
((localTime + (locale -> actualMeetingTz)) -> actualUtcTime;
(actualUtcTime + onlineUserTz) -> actualOnlineUserTime.


Подробнее тут (на аглиском): codeblog.jonskeet.uk/2019/03/27/storing-utc-is-not-a-silver-bullet/comment-page-2/#comment-59146
locale -> actualMeetingTz — это не так просто как кажется. Насколько я знаю, не существует стандартного способа это вычислить. Есть различные сервисы, но они обычно или денег стоят или в оффлайн уходить любят. Можно конечно и локально базу с маппингом хранить, но её где-то взять надо и обновлять потом. IMO, проще просто хранить таймзону.
Вот только что делать если пользователь назначил митинг лет так через 100. Или, наоборот, зная, что лет 100 назад в Париже в 11:30 произошел митинг вы захотите узнать сколько времени в этот момент было в Бо́бо-Диула́со. И какой временной пояс вы собираетесь хранить? Или вы попросите пользователя указать еще и его? А не знает или ошибся, ну так это его проблема?

И какой временной пояс вы собираетесь хранить? Или вы попросите пользователя указать еще и его?

Для митингов с указанием физической локации вытягиваем из локации, для онлайн-митингов на выбор:


  • дефолтную для организации/юнита/группы
  • локальную пользователя из системных настроек
  • локальную пользователя по геоданным
  • локальную пользователя по его настройкм
  • что-то ещё
    возможно с приоритетами и фолбэками. И показ пользователю с подтверждением и/или возможностью исправить
Vadem, написал, что из локации вытащить трудно, а поэтому проще хранить TZ а не локацию. Вопрос был, как тогда узнать TZ.

Под TZ сейчас многие понимают не TZ, а TZ Offset. Вы что понимаете?

Я под TZ понимаю временной пояс. В смысле набор правил, по которым вычисляется смещение от UTC. Вот только проблема в том, что в разные моменты времени к одной и той же точке на земном шаре могут быть привязаны разные временные пояса.

Могут быть, да. Только в России на моей памяти несколько переходов было таких, что одна точка переходила в разные часовые пояса. Но закладываться на это сильно я бы не стал, если нет особых требований к железобетонности решения задачи своевременного уведомления о митинге через 100 лет. Проще следить за анонсами и уведомлять пользователей по типу "вы запланировали митинг 14 декабря 2119-го в часовом поясе Europe/Paris, некоторые места (список или ссылка), которые ранее входили в него, с 1 мая 2067-го в него входить не будут. Проверьте актуальность часового пояса для этого митинга.", если локация, как физическая точка или хотя бы пятно, отсутствует".

А зачем все эти сложности, если достаточно сохранить локальное время и точку, как я предложил изночально, а все остальное вычислять при показе или генерации уведомления?

Ведь на самом деле пользователь не «планировали митинг… в часовом поясе Europe/Paris» он планировал его просто в Париже. Все остальное это костыли, которые придумываем мы, разработчики.

Сразу сказу, что онлайн-митинг — это отдельная проблема, а сейчас мы обсуждаем простую встречу в физической точке на поверхности земного шара (как у автора в задаче).

Если даже он указал нам, что планировал её именно в Париже, я бы часовой пояс вычислил на момент указания и сохранил бы отдельно. Создав параллельно процесс перевычисления при изменении границ зоны.

Дайте угадаю — для оптимизации? Типа изменение этого параметра маловероятно и позволит сэкономить один шаг при показе? Тем более если locale -> TZ действительно требует больших (сравнительно) затрат. Или вы что-то иное имели в виду?

Не только и не столько. Вернее для оптимизации, но не вычислительных ресурсов: есть у меня гипотеза, что средствами "стандартного" SQL вычислить из локации таймзону даже на текущий момент нетривиально, мягко говоря, будет. На ЯП общего назначения это будет гораздо проще и сделать, и поддерживать в дальнейшем, особенно если хранить рядом с остальными полями, что позволит использовать простой WHERE.


Оптимизация вычресурсов: бесплатный бонус. Инвалидация — плата за удобство.

Понятно.
Меня эта задача заинтересовала больше в академическом плане, типа списка необходимых и достаточных данных. В этом плане часовой пояс не нужен. Но при имплементации, как вы правильно заметили, возможен вариант, когда его хранение оправдано.

Ну да, в этом плане достаточно физической точки и какой-то актуальной базы часовых поясов. По крайней мере для относительно стационарных точек на Земле. Какие-нибудь рандеву на МКС или онлайн-митинги скорее требуют прямого указания часового пояса от пользователя или попыток его автоматического определения.

tzdata и аналоги, позволяют переводить из зоны в зону хоть в прошлом, хоть в обозримом будущем. Или я неправильно понял про "вычислить"?

Зарегистрируйтесь на Хабре, чтобы оставить комментарий