Хранение информации о времени: требуется часовой пояс?

Мне интересно узнать, что я рассматриваю, это плохая практика, или если это конкретный и преднамеренный выбор, это на самом деле достойная идея. Я хочу хранить информацию о датах для событий, которые происходят в определенных городах. Я хочу сохранить эти данные как отметки времени UTC. Не было бы хорошей идеей просто сохранить метку времени и идентификатор id города / страны (связанный с конкретным часовым поясом), вместо того, чтобы хранить часовой пояс для каждого события? Я прошу, потому что timezones могут измениться, но идентификаторы города никогда не будут меняться в БД. Как только сервер будет синхронизирован с последним часовым поясом в (маловероятном) событии изменения часового пояса, событие будет независимым и не затронутым этим изменением. Однако, скажем, часовой пояс изменяет свои границы, тогда события, которые произошли в этом часовом поясе ранее, могли быть вне его. Разве это неразумно это делать? Мне просто интересно, и я искал лучшие практики, но в этом случае это действительно похоже на идею OK. Это работает особенно потому, что модель дизайна приложения никогда не изменится – события ВСЕГДА будут связаны с конкретным городом.

Основным потоком будет:

  • Данные о событиях с датой / местоположением поступают в систему в стандартном формате, таком как строка ISO-8601 YYYY-MM-DD.

  • Система преобразует дату в метку времени UTC и сохраняет дату с событием, используя эту метку времени и идентификатор города для события.

  • Когда пользователь запрашивает просмотр этого события, система извлекает временную метку и информацию о городе, связанную с этим событием, и использует часовой пояс города для форматирования даты соответственно на дисплее.

Это ужасная идея? Есть ли польза для этого, и является ли концепция хранения TZ Offset той же идеей, чтобы устранить эту проблему?

Каким бы способом вы это ни делали, он будет терпеть неудачу по-разному в зависимости от того, что меняется.

  1. Если вы сохраняете отметки времени в соответствующем часовом поясе в 2013-12-29 12:34:56 America/New_York , это провалится, если, скажем, Bronx внезапно начнет свой собственный часовой пояс America/New_York_Bronx с другим смещением, и ваше событие оказалось в Бронксе.

    Решите, насколько это возможно, и насколько плохим может быть неудача.

  2. Если вы сохраняете отметки времени в UTC, а часовой пояс, в котором происходит событие, переопределяет их смещение (например, смещение дат DST вокруг или полностью переход на другое смещение), время события может отличаться от фактического времени настенных часов в этом месте. Если вы будете хранить 2013-12-29 12:34:56 UTC для события в 13:34:56 в Берлине, Германии и Берлине, 2013-12-29 12:34:56 UTC свой DST, 2013-12-29 12:34:56 UTC может теперь соответствовать 14:34:56 Берлин по местному времени, в то время как событие по-прежнему происходит в 13:34 по местному времени.

    Решите, насколько это возможно, и насколько плохим может быть неудача.

  3. Если вы сохраняете временную метку UTC и связываете ее с физическим местоположением, которое затем ссылается на часовой пояс, вы можете противостоять обеим проблемам. Но для этого вам нужно будет сохранить точное физическое местоположение, а не только «Нью-Йорк», иначе у вас будет только случай 1. с еще одним промежуточным шагом. Если вы храните точное физическое местоположение и имеете точный способ разрешить это местоположение в часовом поясе, и вы постоянно обновляете базу данных часового пояса, вы можете обрабатывать практически все сценарии изменений.

    Решите, насколько это практично и насколько эта дополнительная точность стоит для вас.

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

Для прошлых событий все, что вам действительно нужно, это локальная дата и время и смещение от UTC (многие платформы называют это «DateTimeOffset»).

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

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

Я уже писал об этом несколько раз ( здесь , здесь и здесь ). Я предлагаю вам прочитать эти сообщения.

Теперь вы подняли одну точку, о которой я раньше не касался, иначе я бы поставил ваш вопрос как дубликат. То есть – что, если местоположение события переместится в новый часовой пояс целиком из-за изменения границ часовых поясов?

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

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

Также обратите внимание, что база данных часовых поясов IANA, которая является исходным источником данных часового пояса, не хранит данные границ вообще! Большинство граничных данных поступают из независимых источников, таких как шейп-файлы Эрика Мюллера , которые на сегодняшний день сопоставляются с данными базы данных IANA за 2013 год (которая находится в 2013 году), поэтому было зарегистрировано не менее 7 обновлений данных часового пояса которые либо не меняли границ, либо изменения не отслеживались.

Когда мы переносили наш проект с британского хостинга на американские машины, некоторые данные, которые были сохранены как DATETIME, были проблематичными, когда нам приходилось отображать данные клиентам. Нам приходилось время от времени настраивать конфигурацию сервера, но это привело к тому, что даты в виде строк или дат timestamp в db, зависящие от конфигурации сервера, не являются хорошей идеей. с тех пор мы используем временные метки unix для любых дат в системе, и мы избавляемся от проблемы с тайм-зонами один раз для всех. Клиенты решают использовать часовой пояс, что бы они ни хотели видеть. Гораздо проще рассчитать разницу во времени, данные фильтра и так далее.

Единственная проблема – убедиться, что введенные данные в систему правильно преобразованы в временную метку unix. Это означает, что пользователь, который вводит данные, должен иметь (в вашем случае) часовой пояс события, когда дата преобразуется в часовой пояс, иначе пользователю нужно будет самостоятельно вычислить часовой пояс.