Обработка часовых поясов в хранилище? - PullRequest
20 голосов
/ 15 августа 2008

Хранить все по Гринвичу?

Сохранить все как было введено со встроенным смещением?

Есть ли математика каждый раз, когда вы делаете?

Отобразить относительное время "1 минуту назад"?

Ответы [ 13 ]

36 голосов
/ 15 августа 2008

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

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

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

Часто в базах данных в прошлом я сохранял два - UTC для сортировки, местное время для отображения. Таким образом, ни пользователь, ни компьютер не запутаются.

Теперь, что касается отображения: Конечно, вы можете делать «3 минуты назад», но только если вы храните UTC - в противном случае данные, введенные в разных часовых поясах, будут выполнять такие действия, как отображение «-4 часа назад». , который будет пугать людей. Если вы собираетесь отображать фактическое время, людям нравится, когда оно отображается по местному времени, а если данные вводятся в нескольких часовых поясах, вы можете легко это сделать, только если вы храните UTC.

13 голосов
/ 25 сентября 2008

Ответ, как всегда, «зависит».

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

Существуют определенные преимущества в хранении данных в UTC time_t - это единственное целое число, обеспечивающее быструю сортировку и простое хранение.

Я вижу, что проблема разбита на определенные области:

  1. Исторические данные
  2. Future, краткосрочные данные
  3. Будущее, долгосрочные данные

Со следующими подклассами на каждом:

  1. Предоставленная система
  2. Предоставлено пользователем

Давайте посмотрим на них по одному.

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

Исторические данные : Это такие вещи, как файлы системного журнала, статистика процесса, трассировка, дата / время комментариев и т. Д. Данные не будут меняться, а дескриптор часового пояса не будет изменить задним числом. Для данных такого типа информация не теряется при хранении информации в формате UTC независимо от часового пояса, в котором она была предоставлена. Поэтому удалите часовой пояс.

Будущие, долгосрочные данные : Это события, которые либо достаточно далеко в будущем, либо будут происходить. Если они хранятся достаточно долго, дескрипторы часовых поясов гарантированно меняются. Хорошим примером такого типа данных является «Еженедельное собрание руководства». Это данные, которые вводятся один раз, и ожидается, что они будут работать вечно. Для этих значений важно определить, предоставлены ли они системой или пользователем. Для предоставленных пользователем данных время должно храниться вместе с часовым поясом создателя, все остальное приведет к потере информации. Эта потеря информации становится очевидной, когда меняется определение часового пояса, и время отображается для создателя как имеющее совершенно другое значение!

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

Будущие, краткосрочные данные : Это данные, которые быстро станут историческими или действительными только в течение короткого периода времени. Примерами могут быть интервальные таймеры, рейтинговые переходы и т. Д. Для этих данных, поскольку вероятность того, что определение изменится между созданием значения и временем, когда оно станет историческим, может оказаться возможной, если отбросить часовой пояс. Однако я обнаружил, что эти ценности имеют плохую привычку превращаться в «Будущие, долгосрочные данные».

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

  • Не храните часовой пояс как смещение или полный дескриптор.

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

  • Храните его как имя.

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

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

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

5 голосов
/ 25 сентября 2008

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

Рассмотрим случай повторной встречи. Это происходит в GMT 0000 (для простоты), что составляет 1200 NZST (стандартное время Новой Зеландии) и 1000 AEST в Сиднее, Австралия.

Когда летнее время вступает в силу в одной зоне, что должно произойти с назначением? Если это:

1a. Если изменение TZ находится в зоне назначение "владелец" (кто забронировал его) затем попытка остаться на такое же время на столе (например, 10:00 утра)?
1б. Если Смена ТЗ в одном из других Зоны участников встречи, то нет изменить

Последствия: оно движется за все остальные, неожиданно, из-за владельцы ТЗ меняются, но остаются "Встреча 10 утра", насколько владелец обеспокоен.

2. Как указано выше, но в обратном порядке.

Последствия: оно переносится для владельца собрания (собрание в 10:00 становится собранием в 9:00, или v / v), что может быть ожидаемым, но неудобным. Он остается в то же время настольных часов для других участников, пока они не пройдут через свой собственный переход TZ.

Ни один не совершенен. Рассмотрим случай двух встреч, один из которых забронирован Лицом А в 10:00 по местному времени, а другой забронирован Лицом Б с Лицом А в качестве посетителя в 9:00. Если Лицо A и Лицо B находятся в разных TZ, изменение DST может легко привести к двойному бронированию.

Если ваш ум немного согнут в этой точке, тогда я вполне понимаю.

Смысл этого примера в том, что для правильного выполнения любого из этих способов поведения вам необходимо знать не только версию местного времени в формате UTC, но и TZ (а не смещение), в котором владелец находился, когда они бронировали его. В противном случае у вас нет выбора, кроме как выбрать вариант 2, молча, даже не сообщая никому, что все изменилось, поскольку время по Гринвичу не меняется, а меняется только презентация ... верно? (нет, это ловушка, презентация имеет значение, когда ваша встреча в 10 утра проходит сама по себе)

Я должен поблагодарить моего коллегу и друга Джейсона Поллока за это понимание. Прочитайте его мнение здесь и последующее обсуждение iCal и VTIMEZONE здесь.

2 голосов
/ 09 июля 2009

Хранение всего в GMT / UTC мне кажется наиболее логичным. Затем вы можете показать дату и время в любом часовом поясе.

Несколько советов:

  1. Если время указано только как время настенные часы, и это ведущее представительство, то это не совсем определенное время. Вы должны (и не можете) конвертировать его в любом представлении GMT. НАПРИМЕР. 9:00 AM каждое утро. Другими словами: это не время (дата).
  2. Если вы сохранить дату и время будущего назначение, вы должны использовать смещение по Гринвичу, указанное входом часовой пояс и момент времени сама . Так что, если это назначение летом сделано зимой, например Западная Европа, это +2: 00, все нормально (зимнее время) смещение +1: 00. Это решит проблема каландра, что Bwooce упоминается.
  3. Конечно, то же самое это относится к использованию права смещение при конвертации в GMT применяется при преобразовании обратно в дата и время в любом конкретном часовой пояс.

К счастью, при правильном использовании тип DateTime (.NET) позаботится обо всех подробностях хранения календарей и т. Д., И все это должно быть очень легко, если вы знаете, как он работает.

1 голос
/ 19 сентября 2012

Посмотрите здесь, w3c отлично справился с ответом на вопрос.

Посмотрите на варианты использования.

http://www.w3.org/TR/timezone/

Обратите внимание, что они рекомендуют хранить дату и время по Гринвичу, а не по Гринвичу, по Гринвичу летнее время.

1 голос
/ 16 октября 2008

Я предпочитаю хранить все с часовым поясом. клиент может решить, каким образом это должно быть представлено позже. Моя любимая библиотека для конвертирования - PostgreSQL-Database .

1 голос
/ 15 августа 2008

MS Dynamics хранит GMT, а затем на уровне пользователя знает ваш часовой пояс относительно GMT. Затем он отображает элементы в вашем часовом поясе.

Просто подумал, что я добавлю это, потому что это очень большая группа в MS, и именно так они решили с этим справиться.

1 голос
/ 15 августа 2008

Итак, я провел небольшой эксперимент с MSSQL-сервером.

Я создал таблицу и добавил строку с текущим локализованным часовым поясом (Австралия). Затем я изменил дату и время на GMT и добавил еще одну строку.

Даже если эти строки были добавлены с интервалом около 10 секунд, они появляются на SQL-сервере, как если бы они были с интервалом в 10 часов.

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

1 голос
/ 15 августа 2008

Лично я не вижу причин, чтобы не хранить все в GMT, а затем использовать локальный часовой пояс пользователей для отображения времени, связанного с ними.

Если вы хотите отобразить относительное время, вам, очевидно, все еще нужно время и сделать перевод, но если вы хотите сделать перевод, я думаю, что GMT по-прежнему ваш лучший вариант.

0 голосов
/ 22 февраля 2019

Даты должны храниться в формате UTC, ЕСЛИ БЕЗ предоставленных пользователем данных, и вы НЕ МОЖЕТЕ знать, в каком часовом поясе пользователь предполагал эти данные. Иногда (очень очень редко) вам нужно просто сохранить часы, минуты, секунды, день, компоненты месяца и года без часового пояса, чтобы вы могли выплюнуть его обратно пользователю. Теперь для новых разработчиков или, если вы не уверены, сохраните UTC, и вы будете на 99% правы.

Но не обманывайте себя, полагая, что это работает 100% времени для всех случаев все время. Это не так.

...