Переход на летнее время и часовой пояс [закрыт]

2048

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

Если вам есть что добавить, пожалуйста

Многие системы зависят от сохранения точного времени, проблема заключается в изменениях времени из-за перехода на летнее время - перемещения часов вперед или назад.

Например, в системе приема заказов есть бизнес-правила, которые зависят от времени заказа - если часы изменятся, правила могут быть не такими ясными. Как сохранить время заказа? Есть, конечно, бесконечное количество сценариев - это просто иллюстративный.

  • Как вы справились с проблемой перехода на летнее время?
  • Какие предположения являются частью вашего решения? (ищите контекст здесь)

Как важно, если не больше так:

  • Что ты пробовал, чтобы не получилось?
  • Почему это не сработало?

Я был бы заинтересован в программировании, ОС, сохранности данных и других соответствующих аспектах проблемы.

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

Одед
источник
2
@abatishchev - таким образом, GETDATE()на SQL будет UTC (как будет DateTime.Now). И сервер не будет зависеть от каких-либо автоматических изменений DST.
Одед
4
@Oded: Я могу согласиться, если будет добавлено «на сервере». Но все же это может повлиять на другие приложения, которые требуют местного времени. По этой и другим причинам я думаю, что лучше запросить время Utc явно.
Абатищев
7
UTC предпочтительнее GMT, поскольку оно более точно определено и потому, что определения GMT испорчены в некоторых операционных системах. Люди часто воспринимают термины «GMT» и «UTC» как взаимозаменяемые, но они не полностью. Практически для любого программного / системного назначения используйте UTC. См. Stackoverflow.com/questions/2292334/…
Крис Джонсон
7
@JoshStodola - « ответ » Джона Скита .
Кенни Эвитт
1
@ Сейчас вы не можете предполагать, что сервер будет в UTC, я видел рабочие серверы, где часовой пояс был "UTC", но применялось летнее время, так что на самом деле было UTC + 1 более полугода. Согласитесь с @abatishchev, чтобы он был явным и использованным, DateTime.UtcNowи GETUTCDATE()он также показывает других разработчиков, которые вы на самом деле думали об этом
ono2012

Ответы:

940

Резюме ответов и других данных: (пожалуйста, добавьте свои)

Делать:

  • Всякий раз, когда вы ссылаетесь на точный момент времени, сохраняйте время в соответствии с единым стандартом, который не зависит от перехода на летнее время. (GMT и UTC эквивалентны в этом отношении, но предпочтительнее использовать термин UTC. Обратите внимание, что UTC также называется Zulu или Z time.)
  • Если вместо этого вы выберете сохранение времени с использованием значения местного времени, включите смещение местного времени для этого конкретного времени из UTC (это смещение может изменяться в течение года), чтобы впоследствии можно было однозначно интерпретировать временную метку.
  • В некоторых случаях вам может понадобиться для хранения как время UTC и локальное время. Часто это делается с двумя отдельными полями, но некоторые платформы поддерживают datetimeoffsetтип, который может хранить оба в одном поле.
  • При сохранении временных меток в виде числового значения используйте Unix time - это количество целых секунд с 1970-01-01T00:00:00Z(без учета високосных секунд). Если вам требуется более высокая точность, используйте вместо этого миллисекунды. Это значение всегда должно основываться на UTC, без какой-либо настройки часового пояса.
  • Если впоследствии вам может понадобиться изменить временную метку, включите исходный идентификатор часового пояса, чтобы вы могли определить, изменилось ли смещение относительно исходного записанного значения.
  • При планировании будущих событий обычно предпочтительнее местное время, а не UTC, поскольку смещение обычно меняется. Смотрите ответ и сообщение в блоге .
  • При сохранении целых дат, таких как дни рождения и годовщины, не конвертируйте в UTC или любой другой часовой пояс.
    • По возможности сохраняйте данные только для даты, которые не включают время суток.
    • Если такой тип недоступен, обязательно всегда игнорируйте время суток при интерпретации значения. Если вы не можете быть уверены в том, что время суток будет игнорироваться, выберите 12:00 полдень, а не 00:00 полночь в качестве более безопасного репрезентативного времени в этот день.
  • Помните, что смещения часового пояса не всегда являются целым числом часов (например, индийское стандартное время - UTC + 05: 30, а Непал использует UTC + 05: 45).
  • Если вы используете Java, используйте java.time для Java 8 и новее.
  • Если вы используете .NET , рассмотрите возможность использования Noda Time .
  • Если вы используете .NET без Noda Time, учтите, что DateTimeOffsetэто часто лучший выбор, чем DateTime.
  • Если вы используете Perl, используйте DateTime .
  • При использовании Python, используйте pytz или dateutil .
  • Если вы используете JavaScript, используйте moment.js с расширением moment-timezone .
  • При использовании PHP> 5.2, использовать собственные преобразования часовых поясов , предоставляемые DateTimeи DateTimeZoneклассы. Будьте осторожны при использовании DateTimeZone::listAbbreviations()- смотрите ответ . Чтобы поддерживать PHP в актуальном состоянии с данными Олсона, периодически устанавливайте PECL-пакет timezonedb ; смотри ответ .
  • Если вы используете C ++, обязательно используйте библиотеку, которая правильно использует базу данных часовых поясов IANA . К ним относятся cctz , ICU и библиотека "tz" Говарда Хиннанта .
    • Не используйте Boost для преобразования часовых поясов. Хотя его API утверждает, что поддерживает стандартные идентификаторы IANA (он же «zoneinfo»), он грубо сопоставляет их с данными в стиле POSIX, не учитывая богатую историю изменений, которые могла иметь каждая зона. (Также файл вышел из строя.)
  • Если вы используете Rust, используйте Chrono .
  • Большинство бизнес-правил используют гражданское время, а не UTC или GMT. Поэтому планируйте преобразовывать временные метки UTC в местный часовой пояс перед применением логики приложения.
  • Помните, что часовые пояса и смещения не являются фиксированными и могут меняться. Например, исторически США и Великобритания использовали одни и те же даты, чтобы «прыгнуть вперед» и «отступить». Тем не менее, в 2007 году США изменили даты, на которые меняются часы. Это означает, что в течение 48 недель в году разница между лондонским и нью-йоркским временем составляет 5 часов, а в течение 4 недель (3 весной, 1 осенью) - 4 часа. Будьте внимательны к таким элементам в любых вычислениях, которые включают несколько зон.
  • Рассмотрите тип времени (фактическое время события, время вещания, относительное время, историческое время, повторяющееся время), какие элементы (временная метка, смещение часового пояса и имя часового пояса) вам нужно сохранить для правильного поиска - см. «Типы времени» в этот ответ .
  • Синхронизируйте файлы tzdata вашей ОС, базы данных и приложений между собой и остальным миром.
  • На серверах установите аппаратные часы и часы ОС на UTC, а не на местный часовой пояс.
  • Независимо от предыдущего пункта, серверный код, включая веб-сайты, никогда не должен ожидать, что локальный часовой пояс сервера будет чем-то конкретным. смотри ответ .
  • Предпочитайте работать с часовыми поясами в каждом конкретном случае в коде приложения, а не глобально через настройки файла конфигурации или значения по умолчанию.
  • Используйте сервисы NTP на всех серверах.
  • При использовании FAT32 помните, что временные метки хранятся по местному времени, а не по UTC.
  • При работе с повторяющимися событиями (например, еженедельным телешоу) помните, что время меняется в зависимости от летнего времени и будет различным в разных часовых поясах.
  • Всегда запрашивайте значения даты и времени как включающие нижнюю границу, исключающую верхнюю границу ( >=, <).

Не рекомендуется:

  • Не путайте «часовой пояс», такой как America/New_York«смещение часового пояса», например -05:00. Это две разные вещи. Смотрите тег часового пояса вики .
  • Не используйте Dateобъект JavaScript для выполнения вычислений даты и времени в старых веб-браузерах, поскольку ECMAScript 5.1 и ниже имеет недостаток дизайна, который может неправильно использовать летнее время. (Это было исправлено в ECMAScript 6/2015).
  • Никогда не доверяй часам клиента. Это может быть очень неправильно.
  • Не говорите людям «всегда используйте UTC везде». Этот широко распространенный совет близок к нескольким действительным сценариям, которые описаны ранее в этом документе. Вместо этого используйте соответствующую временную привязку для данных, с которыми вы работаете. ( Временная метка может использовать UTC, но не следует использовать будущее расписание и значения только для даты.)

Тестирование:

  • При тестировании убедитесь, что вы тестируете страны в Западном, Восточном, Северном и Южном полушариях (фактически в каждой четверти земного шара, а значит, в 4 регионах), причем в настоящее время идет как ТЛЧ, а не (дает 8), так и страна, которая это делает. не использовать DST (еще 4, чтобы охватить все регионы, в сумме 12).
  • Проверьте переход на летнее время, т. Е. Когда вы находитесь в летнее время, выберите значение времени из зимы.
  • Тестируйте граничные случаи, такие как часовой пояс UTC + 12 с DST, делая местное время UTC + 13 летом и даже места с UTC + 13 зимой
  • Протестируйте все сторонние библиотеки и приложения и убедитесь, что они правильно обрабатывают данные часового пояса.
  • Проверьте полчаса часовых поясов, по крайней мере.

Ссылка:

Другой:

  • Лоббировать вашего представителя, чтобы положить конец мерзости, которая является DST. Мы всегда можем надеяться ...
  • Лобби по стандартному времени Земли
Мэтт Джонсон
источник
31
Использование GMT ​​на самом деле не решает проблему, вам все равно нужно выяснить, какую именно дельту следует применять, и в этом вся сложность. Дельта может быть сложной для определения в системах, которые используются пользователями в разных регионах (с разными графиками перехода на летнее время) или в системах, показывающих исторические / будущие данные.
ckarras
10
Это верно, если все, что нужно приложению, это отображать текущее местное время. Но если у нас есть, например, сервер в Австралии, который должен отображать дату / время для транзакции в Канаде 2 апреля 2006 г. (это был последний год перед тем, как правила перехода на летнее время изменились в Канаде) - у вас есть вызов ОС что может делать DateTime ("2006/04/02 14: 35Z"). ToLocalTime (). WithDaylightSavingRules ("Canada", 2006)?
ckarras
22
Да, в Windows есть такой вызов ОС - SystemTimeToTzSpecificLocation. msdn.microsoft.com/en-us/library/ms724949(VS.85).aspx
Майкл Мэдсен,
7
@ tchrist Может быть, если вы настойчивы, вы можете.
Питер Айтай
16
Имейте в виду, что при преобразовании будущих дат (даже только завтра) в UTC вы всегда что-то теряете. Например, вы использовали какое-то известное смещение для этого преобразования, но поскольку дата находится в будущем, всегда есть вероятность, что группа, которая устанавливает эти правила, изменит эти правила. Кроме того, практически невозможно преобразовать некоторые будущие даты в UTC, поскольку переход на летнее время неизвестен до этого года (некоторые страны устанавливают даты каждый год, а не на 10+ лет вперед или на основании каких-либо установленных правил).
Eselk
319

Я не уверен, что я могу добавить к ответам выше, но вот несколько моментов от меня:

Типы времени

Есть четыре разных момента, которые вы должны рассмотреть:

  1. Время события: например, время, когда происходит международное спортивное событие, или коронация / смерть / и т.д. Это зависит от часового пояса события, а не от зрителя.
  2. Телевизионное время: например, конкретное телевизионное шоу транслируется в 21:00 по местному времени по всему миру. Важно подумать о публикации результатов (скажем, American Idol) на вашем сайте
  3. Относительное время: например: этот вопрос закрывается за 21 час. Это легко отобразить
  4. Время повторения: например: ТВ-шоу каждый понедельник в 21:00, даже если меняется летнее время.

Существует также историческое / альтернативное время. Это раздражает, потому что они не могут вернуться к стандартному времени. Например: Юлианские даты, даты в соответствии с лунным календарем на Сатурне, клингонским календарем.

Хранение времени начала / окончания в UTC работает хорошо. Для 1 вам нужно имя часового пояса события + смещение, сохраненное вместе с событием. Для 2 вам нужен локальный идентификатор времени, сохраненный для каждого региона, и имя локального часового пояса + смещение, сохраненное для каждого зрителя (это можно получить из IP, если вы находитесь в затруднительном положении). Для 3 храните в секундах UTC и нет необходимости в часовых поясах. 4 - это особый случай 1 или 2, в зависимости от того, является ли это глобальным или локальным событием, но вам также необходимо сохранить созданное с отметкой времени, чтобы вы могли определить, изменилось ли определение часового пояса до или после создания этого события. Это необходимо, если вам нужно показать исторические данные.

Время хранения

  • Всегда хранить время в UTC
  • Преобразование в местное время на дисплее (локально определяется пользователем, смотрящим на данные)
  • При сохранении часового пояса вам необходимо указать имя, временную метку и смещение. Это необходимо, потому что правительства иногда меняют значения своих часовых поясов (например, правительство США изменило даты перехода на летнее время), и ваше приложение должно обрабатывать вещи изящно ... например: точная временная метка, когда эпизоды LOST показывали как до, так и после правил перехода на летнее время изменилось.

Смещения и имена

Примером вышеупомянутого будет:

Финал кубка мира по футболу состоялся в Южной Африке (UTC + 2 - SAST) 11 июля 2010 года в 19:00 UTC.

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

Системное время

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

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

Также запустите ntpd на всех компьютерах.

клиенты

Никогда не доверяйте действительной отметке времени, полученной с клиентского компьютера. Например, Date: HTTP-заголовки или Date.getTime()вызов JavaScript . Это хорошо, когда они используются в качестве непрозрачных идентификаторов или когда выполняются вычисления даты во время одного сеанса на одном и том же клиенте, но не пытайтесь сопоставлять эти значения с чем-то, что есть на сервере. Ваши клиенты не запускают NTP и могут не обязательно иметь работающую батарею для своих часов BIOS.

пустяки

Наконец, правительства иногда делают очень странные вещи:

Стандартное время в Нидерландах было ровно на 19 минут и на 32,13 секунды больше, чем UTC по закону с 1909-05-01 по 1937-06-30. Этот часовой пояс не может быть точно представлен в формате ЧЧ: ММ.

Хорошо, я думаю, что я закончил.

bluesmoon
источник
6
В этом ответе есть несколько замечательных моментов, особенно я хотел бы отметить эту часть: «Повторяющееся время: например, телешоу каждый понедельник в 21:00, даже когда меняется летнее время». Сохранение времени в формате UTC в БД, а затем преобразование для отображения помогает обрабатывать много сложных аспектов работы с часовыми поясами. Однако обработка "повторяющихся событий", которые пересекают барьеры DST, становится намного более сложной.
Джаред Хейлз
45
+1 за мелочи. Интересное содержание делает эту задачу более приятной, что может привести к повышению производительности :)
Крис
4
В этом ответе много хорошего, но есть несколько вопросов. 1) Многие сокращения часовых поясов неоднозначны. смотри здесь 2) Не всегда хочешь хранить в UTC. Большую часть времени - да, но контекст имеет значение. По вашему мнению, телевизионное время не будет храниться в UTC. Кроме того, иногда незаконно или против политики не хранить местное время - вот где такие вещи, как DateTimeOffset(или эквивалент), пригодятся. В противном случае хорошо написать.
Мэтт Джонсон-Пинт
1
Итак, все согласны с тем, что библиотека Joda, безусловно, является лучшим инструментом для работы. Однако нам необходимо постоянно обновлять (перестраивать) JAR-файл JODA согласно этой статье ( joda.org/joda-time/tz_update.html ), чтобы быть в курсе последних данных о часовых поясах. Есть ли какой-либо стандартный способ загрузки последних данных о часовых поясах с веб-сайта IANA ( iana.org/time-zones ) и восстановления библиотеки joda? Другими словами, возможно ли автоматизировать этот процесс, а не делать это вручную?
saravana_pc
2
Пустяки Нидерландов выглядят законными. ietf.org/rfc/rfc3339.txt раздел 5.8. На полпути понял, что кто-то тянет нашу ногу.
Ерф
89

Это важный и удивительно сложный вопрос. Правда в том, что не существует полностью удовлетворяющего стандарта для постоянного времени. Например, стандарт SQL и формат ISO (ISO 8601) явно недостаточны.

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

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

«Гражданское» время - это спецификация даты и времени, которая следует гражданским нормам: момент времени здесь полностью определяется набором полей даты и времени (Y, M, D, H, MM, S, FS) плюс TZ (спецификация часового пояса). (на самом деле также «календарь»; но давайте предположим, что мы ограничиваем обсуждение григорианским календарем). Часовой пояс и календарь совместно позволяют (в принципе) отображать из одного представления в другое. Но моменты гражданского и физического времени - это принципиально разные типы величин, и они должны концептуально разделяться и обрабатываться по-разному (аналогия: массивы байтов и символьные строки).

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

Джон записывает в своем календаре напоминание о каком-то событии в дату-время 2019-Jul-27, 10:30:00, TZ = Chile/Santiago, (которое имеет смещение GMT-4, следовательно, оно соответствует UTC 2019-Jul-27 14:30:00). Но когда-нибудь в будущем страна решит изменить смещение TZ на GMT-5.

Теперь, когда придет день ... должно ли это напоминание вызвать

А) 2019-Jul-27 10:30:00 Chile/Santiago = UTC time 2019-Jul-27 15:30:00?

или

Б) 2019-Jul-27 9:30:00 Chile/Santiago = UTC time 2019-Jul-27 14:30:00?

Правильного ответа нет, если только вы не знаете, что концептуально имел в виду Джон, когда говорил календарю: «Пожалуйста, позвоните мне 2019-Jul-27, 10:30:00 TZ=Chile/Santiago».

Он имел в виду «гражданскую дату-время» («когда часы в моем городе показывают 10:30»)? В этом случае А) является правильным ответом.

Или он имел в виду «физический момент времени», точку в непрерывной линии времени нашей вселенной, скажем, «когда произойдет следующее солнечное затмение». В этом случае ответ B) является правильным.

Некоторые API Date / Time правильно понимают это различие: среди них Jodatime , который является основой следующего (третьего!) Java DateTime API (JSR 310).

leonbloy
источник
1
Еще один момент, на который я не обращал внимания в API, заключается в том, что даже когда указаны время и часовой пояс, существует, по крайней мере, два вероятных значения, например, «13: 00: 00EDT». Это может относиться к чему-то, что, как известно, произошло в 13:00 по местному времени, которое, как полагают, было восточным дневным временем, или к чему-то, что, как известно, произошло в тот момент, когда восточное время достигло 13:00, что, как считается, произошли в месте, где наблюдается восточное дневное время. Если есть много временных отметок, где информация о часовом поясе может быть неправильной (например, файлы цифровой камеры) ...
суперкат
1
... зная, отражают ли они точное местное или глобальное время, может быть важно определить, как их исправить.
суперкат
3
Понятно, что Джон хочет А), потому что люди идут на работу в 8:30, независимо от того, какой сейчас DST или часовой пояс. Если они перейдут на летнее время, они пойдут на работу в 8:30, когда они выйдут из летнего времени, они пойдут на работу в 8:30. Если страна решит перейти в другой часовой пояс, они отправятся на работу в 8:30 вечера
Джанлука Геттини,
59

Проведите четкое архитектурное разделение задач - точно знать, какой уровень взаимодействует с пользователями, и должен изменить дату / время для / из канонического представления (UTC). Дата и время не в формате UTC - это представление (следует за часовым поясом пользователя), время в формате UTC - это модель (остается уникальным для внутреннего и промежуточного уровней).

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

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

Если существуют исторические обязательства по аудиту (например, точно сказать, когда Jo in AZ оплатил счет 2 года назад в сентябре), сохраните для учета как UTC, так и местное время (таблицы конверсии со временем изменятся).

Определите временный часовой пояс для данных, которые поступают в больших объемах, таких как файлы, веб-сервисы и т. Д. Скажем, у компании East Coast есть дата-центр в ЦА - вам нужно спросить и узнать, что они используют в качестве стандарта вместо того, чтобы предполагать одно или другое.

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

ZXX
источник
40

Вам необходимо знать о базе данных Olson tz , доступной по адресу ftp://elsie.nci.nih.gov/pub http://iana.org/time-zones/ . Он обновляется несколько раз в год, чтобы справляться с часто меняющимися в последний момент изменениями того, когда (и нужно ли) переключаться между зимним и летним (стандартным и летним) временем в разных странах мира. В 2009 году последний выпуск был 2009-х годов; в 2010 году это было 2010n; в 2011 году это было 2011n; в конце мая 2012 года был выпущен 2012c. Обратите внимание, что в двух отдельных архивах (tzcode20xxy.tar.gz и tzdata20xxy.tar.gz) имеется набор кода для управления данными и собственно данными о часовом поясе. И код, и данные находятся в свободном доступе.

Это источник названий часовых поясов, таких как America / Los_Angeles (и синонимов, таких как US / Pacific).

Если вам нужно отслеживать разные зоны, вам нужна база данных Olson. Как и другие советуют, вы также хотите хранить данные в фиксированном формате - обычно выбирается UTC - вместе с записью часового пояса, в котором были сгенерированы данные. Возможно, вы захотите отличить смещение от времени UTC по времени и имени часового пояса; это может изменить ситуацию позже. Кроме того, зная, что в настоящее время 2010-03-28T23: 47: 00-07: 00 (США / Тихий океан) может или не может помочь вам в интерпретации значения 2010-11-15T12: 30 - которое предположительно указано в PST ( Стандартное тихоокеанское время), а не PDT (Тихоокеанское летнее время).

Стандартные интерфейсы библиотеки C не очень полезны для такого рода вещей.


Данные Olson были перенесены, частично из-за того, что AD Olson скоро уйдет на пенсию, и частично из-за того, что был (в настоящее время отклонен) судебный иск против сопровождающих лиц за нарушение авторских прав. База данных часовых поясов теперь управляется под эгидой IANA , Управления по присвоению номеров в Интернете, и на первой странице есть ссылка на « База данных часовых поясов » . Список рассылки обсуждений теперь tz@iana.org; список объявлений есть tz-announce@iana.org.

Джонатан Леффлер
источник
12
База данных Olson также содержит исторические данные, что делает ее особенно полезной для обработки DST. Например, он знает, что значение UTC, соответствующее 31 марта 2000 года в США, не указано в DST, а значение UTC, соответствующее 31 марта 2008 года, в США.
Джош Келли
3
Консорциум Unicode поддерживает соответствие между идентификаторами зон Олсона и томами часовых поясов Windows: unicode.org/repos/cldr-tmp/trunk/diff/supplemental/…
Джош Келли,
Обновлена ссылка на страницу Unicode Консорциума: unicode.org/repos/cldr-tmp/trunk/diff/supplemental/...
Span
Где можно найти информацию о разборе файлов Олсона? Я хочу скомпилировать его в таблицу
базы данных
@gidireich: основная информация находится вместе с данными, и ее нелегко понять. Основная документация для этого находится на zic.8странице руководства (или zic.8.txt). Вам понадобится tzcode2011i.tar.gzфайл, а не tzdata2011i.tar.gzфайл или для получения этой информации.
Джонатан Леффлер
26

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

Имейте в виду, что смещение не всегда является целым числом часов (например, индийское стандартное время - UTC + 05: 30).

Например, подходящими форматами являются кортеж (время Unix, смещение в минутах) или ISO 8601 .

oefe
источник
5
Для отображения смещение идеально. Если вы хотите внести изменения, смещения по-прежнему недостаточно. Вы также должны знать часовой пояс, поскольку для нового значения может потребоваться другое смещение.
Мэтт Джонсон-Пинт
23

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

Некоторые страны, например, Израиль, Бразилия, каждый год решают, когда будет переходить на летнее время, поэтому невозможно заранее знать, когда (если) будет действовать ТЛЧ. Другие имеют фиксированные (ish) правила относительно того, когда действует DST. Другие страны не используют DST как все.

Часовые пояса не должны быть полными часовыми отличиями от GMT. Непал +5,45. Есть даже часовые пояса, которые +13. Что означает, что:

SUN 23:00 in Howland Island (-12)
MON 11:00 GMT 
TUE 00:00 in Tonga (+13)

все время, но 3 разных дня!

Также нет четкого стандарта на аббревиатуры для часовых поясов и то, как они меняются, когда в летнее время, поэтому вы в конечном итоге с такими вещами:

AST Arab Standard Time     UTC+03
AST Arabian Standard Time  UTC+04
AST Arabic Standard Time   UTC+03

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

При тестировании обязательно проверяйте страны в западном и восточном полушариях, причем в настоящее время находится как ТЛЧ, так и нет, а также страну, которая не использует ТЛЧ (всего 6).

Ричард
источник
Что касается Израиля - это наполовину правда. Хотя время для перехода на летнее время не является конкретной датой в юлианском календаре - существует правило, основанное на еврейском календаре (в 2014 году произошло изменение). Во всяком случае, общая идея верна - эти вещи могут и действительно время от времени меняться
Yaron U.
1
Также AST = Атлантическое стандартное время. Что касается «лучшего совета», то это хорошо в качестве отправной точки, но вам нужно прочитать оставшуюся часть этой страницы и произнести небольшую молитву, и вы можете некоторое время сделать ее правильно.
DavidWalley
20

Для PHP:

Класс DateTimeZone в PHP> 5.2 уже основан на базе данных Olson, которую упоминают другие, поэтому, если вы выполняете преобразование часовых поясов в PHP, а не в базе данных, вы освобождаетесь от работы с (трудными для понимания) файлами Olson.

Однако PHP обновляется не так часто, как БД Olson, поэтому простое использование преобразования часовых поясов в PHP может привести к устаревшей информации о летнем времени и повлиять на правильность ваших данных. Несмотря на то , что это не должно было произойти часто, это может произойти, и будет происходить , если у вас есть большая база пользователей по всему миру.

Чтобы справиться с вышеуказанной проблемой, используйте пакет timezonedb pecl . Его функция - обновлять данные часового пояса PHP. Установите этот пакет так часто, как он обновляется. (Я не уверен, что обновления этого пакета точно следуют обновлениям Olson, но, похоже, он обновляется с частотой, которая, по крайней мере, очень близка к частоте обновлений Olson.)

shealtiel
источник
18

Если ваш дизайн может вместить его, избегайте преобразования местного времени все вместе!

Я знаю, что для некоторых это может показаться безумным, но подумайте о UX: пользователи обрабатывают близкие относительные даты (сегодня, вчера, следующий понедельник) быстрее, чем абсолютные даты (2010.09.17, пятница 17 сентября). И когда вы думаете об этом больше, точность часовых поясов (и летнего времени) тем важнее, чем ближе дата now(), поэтому, если вы можете выразить дату / время в относительном формате для +/- 1 или 2 недели, остальные даты могут быть UTC, и это не будет иметь большого значения для 95% пользователей.

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

Это также может относиться и к пользовательскому вводу (но, как правило, более ограниченным образом). Выбор из выпадающего меню, в котором есть только {Вчера, Сегодня, Завтра, Следующий понедельник, Следующий четверг}, намного проще и проще для пользователя, чем выбор даты. Сборщики даты являются одними из самых вызывающих боль компонентов заполнения формы. Конечно, это не будет работать для всех случаев, но вы можете видеть, что для того, чтобы сделать его очень мощным, требуется лишь немного хитрый дизайн.

Мэтт Коджай
источник
16

Хотя я не пробовал это сделать, подход к корректировке часового пояса, который я нашел бы убедительным, был бы следующим:

  1. Храните все в UTC.

  2. Создайте таблицу TZOffsetsс тремя столбцами: RegionClassId, StartDateTime и OffsetMinutes (int, в минутах).

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

Когда вам нужно вычислить местное время для любого времени UTC, просто сделайте это:

SELECT DATEADD('m', SUM(OffsetMinutes), @inputdatetime) AS LocalDateTime
FROM   TZOffsets
WHERE  StartDateTime <= @inputdatetime
       AND RegionClassId = @RegionClassId;

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

Эти данные могут быть извлечены из базы данных общественного достояния tz .

Преимущества и сноски этого подхода:

  1. В коде нет правил, вы можете легко корректировать смещения для новых регионов или диапазонов дат.
  2. Вам не нужно поддерживать каждый диапазон дат или регионов, вы можете добавлять их по мере необходимости.
  3. Регионы не должны напрямую соответствовать геополитическим границам, и во избежание дублирования строк (например, большинство штатов США обрабатывают DST одинаково), вы можете иметь широкие записи RegionClass, которые в другой таблице связаны с более традиционными списками штаты, страны и т. д.
  4. В таких ситуациях, как США, где дата начала и окончания летнего времени изменилась за последние несколько лет, с этим довольно легко справиться.
  5. Поскольку поле StartDateTime также может хранить время, стандартное время переключения 2:00 AM легко обрабатывается.
  6. Не везде в мире используется 1-часовой DST. Это легко обрабатывает эти случаи.
  7. Таблица данных является кроссплатформенной и может представлять собой отдельный проект с открытым исходным кодом, который может использоваться разработчиками, которые используют практически любую платформу базы данных или язык программирования.
  8. Это может использоваться для смещений, которые не имеют ничего общего с часовыми поясами. Например, 1-секундные корректировки, которые происходят время от времени для корректировки вращения Земли, исторические корректировки и в григорианском календаре и т. Д.
  9. Поскольку это находится в таблице базы данных, стандартные запросы отчетов и т. Д. Могут использовать данные без использования кода бизнес-логики.
  10. Это также обрабатывает смещения часового пояса, если вы этого хотите, и может даже учитывать особые исторические случаи, когда регион назначается другому часовому поясу. Все, что вам нужно, это начальная дата, которая назначает смещение часового пояса для каждого региона с минимальной датой начала. Это потребует создания хотя бы одного региона для каждого часового пояса, но позволит вам задать интересные вопросы, такие как: «В чем разница между местным временем между Юмой, штат Аризона, и Сиэтлом, штат Вашингтон, 2 февраля 1989 года в 5:00 утра?» (Просто вычтите одну СУММУ () из другой).

Теперь единственным недостатком этого или любого другого подхода является то, что преобразования из местного времени в GMT не являются совершенными, поскольку любое изменение DST, которое имеет отрицательное смещение по отношению к часам, повторяет данное местное время. Боюсь, нелегкий способ справиться с этим, и это одна из причин, по которой местное время хранится в плохих новостях.

richardtallent
источник
8
Ваша идея базы данных уже реализована как база данных Olson. В то время как переход на летнее время действительно создает наложение, указание часового пояса для летнего времени может помочь решить проблему. 2:15 EST и 2:15 EDT разные времена. Как отмечалось в других сообщениях, указание смещения также устраняет неоднозначность.
BillThor
5
Большая проблема с сохранением вашей собственной базы данных заключается в том, чтобы поддерживать ее в актуальном состоянии. Олсон и Windows поддерживаются для вас. У меня было более одного случая плохих переходов DST, потому что таблицы устарели. Полностью удалить их и полагаться на базу данных уровня базы данных или уровня ОС гораздо надежнее.
Мэтт Джонсон-Пинт
4
Не создавайте свою собственную базу данных : всегда полагайтесь на системный API!
Алекс
15

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

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

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

Из этого я узнал: не используйте JavaScript-вычисления даты и времени в веб-приложениях, если это НЕ АБСОЛЮТНО.

Joon
источник
Javascript запускается на клиентском компьютере, а не на сервере. Базовая дата-время Javascript - это дата-время клиента, а не дата-время сервера.
BalusC
Привет BalusC. Я понимаю это (из моего исходного поста: «скрипт javacode на клиенте, который создал дату ...»). Моя проблема заключалась в том, что определенный клиентский компьютер обрабатывал DST одним способом, а некоторые другие - другим способом. Поэтому я перенес всю эту обработку на серверную часть, чтобы не допустить странностей браузера
Joon
@ Joon - и в реализациях javascript есть ошибки, которые вы не можете обнаружить или учесть. Так что да, никогда не используйте вычисления даты ECMAScript на стороне клиента для важных вещей (хотя в противном случае вы можете сделать довольно хорошую работу).
RobG
14

Я столкнулся с этим на двух типах систем: «системы планирования смены (например, фабричные рабочие)» и «системы управления, зависящие от газа)…

23 и 25-часовой рабочий день - это боль, с которой приходится справляться, также как и 8-часовые смены, которые занимают 7 или 9 часов. Проблема в том, что вы обнаружите, что у каждого клиента или даже отдела клиента есть свои правила, которые они создали (часто без документирования) в отношении того, что они делают в этих особых случаях.

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

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

Ian Ringrose
источник
6
Моя девушка, медсестра, работает по ночам, и они должны написать часовой пояс во время перехода на летнее время. Например, 2:00 CST против 2:00 CDT
Джо Филлипс
1
Да, это обычное явление: когда вы вычисляете (гражданское) среднесуточное значение, вам приходится иметь дело с 23, 24 или 25 днями. Как следствие, при вычислении добавить 1 день это не добавить 24 часа ! Во-вторых, не пытайтесь создать свой собственный код часового пояса; использовать только системный API. И не забудьте обновить каждую развернутую систему, чтобы получить актуальную базу данных часовых поясов .
Алекс
12

Для Интернета правила не так сложны ...

  • Серверная сторона, используйте UTC
  • Клиентская сторона, используйте Olson
    • Причина: смещения UTC не являются безопасным переходом на летнее время (например, Нью-Йорк - EST (UTC - 5 часов) часть года, EDT (UTC - 4 часа) - остальная часть года).
    • Для определения часового пояса на стороне клиента у вас есть два варианта:
      • 1) Пользователь установил зону (безопаснее)
      • 2) Зона автоопределения

Остальное - просто UTC / локальное преобразование с использованием ваших серверных библиотек даты и времени. Хорошо пойти...

Ярин
источник
2
Это хороший совет в качестве отправной точки, но он полностью зависит от приложения. Это может быть хорошо для дружественного веб-сайта, но если в вашем приложении есть какой-либо юридический / юрисдикционный / финансовый аспект, на который кто-то может подать иск (я работал над несколькими), то это чрезмерное упрощение, потому что есть разные виды « время », как отмечено в другом месте на этой странице.
DavidWalley
12

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

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

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

В некоторых языках местный часовой пояс может легко проникнуть в код приложения. Например, DateTime.ToUniversalTimeметод в .NET будет конвертировать из локального часового пояса в UTC, и DateTime.Nowсвойство возвращает текущее время в местном часовом поясе. Кроме того, Dateконструктор в JavaScript использует локальный часовой пояс компьютера. Есть много других примеров, подобных этому. Важно практиковать защитное программирование, избегая любого кода, который использует настройку локального часового пояса компьютера.

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

Мэтт Джонсон-Пинт
источник
11

Держите ваши серверы на UTC и убедитесь, что все они настроены на ntp или эквивалентный.

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

Andrew B
источник
9

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

paquetp
источник
Отличный момент. NTFS не имеет этой проблемы, но некоторые люди все еще используют FAT32 - особенно на USB-ключах.
Мэтт Джонсон-Пинт
7

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

В прошлом году у нас была ситуация, когда наше время постоянно сокращалось на один час в течение трехнедельного периода для пользователей из Северной Америки, хотя мы использовали систему на основе UTC.

Оказывается, в конце концов это были серверы. Им просто нужно было применить современное исправление ( Windows Server 2003 ).

Solyad
источник
6

DateTimeZone::listAbbreviations()Вывод PHP

Этот метод PHP возвращает ассоциативный массив, содержащий некоторые «основные» часовые пояса (например, CEST), которые сами содержат более конкретные «географические» часовые пояса (например, Европа / Амстердам).

Если вы используете эти часовые пояса и информацию о их смещении / DST, очень важно понимать следующее:

Кажется, что все различные конфигурации смещения / DST (включая исторические конфигурации) каждого часового пояса включены!

Например, Европа / Амстердам можно найти шесть раз в выходных данных этой функции. Два события (смещение 1172/4772) относятся к амстердамскому времени до 1937 года; два (1200/4800) для времени, которое использовалось между 1937 и 1940 годами; и два (3600/4800) для времени, используемого с 1940 года.

Таким образом, вы не можете полагаться на информацию о смещении / DST, возвращаемую этой функцией как правильную / используемую в данный момент!

Если вы хотите узнать текущее смещение / летнее время определенного часового пояса, вам нужно будет сделать что-то вроде этого:

<?php
$now = new DateTime(null, new DateTimeZone('Europe/Amsterdam'));
echo $now->getOffset();
?>
Джонатан
источник
5

Если вам случается поддерживать системы баз данных, которые работают с активным DST, внимательно проверьте, нужно ли их отключать во время перехода осенью. Mandy DBS (или другие системы) также не любят дважды проходить одну и ту же точку по (местному) времени, что и происходит, когда вы возвращаете часы назад. SAP решил это с помощью (ИМХО действительно аккуратного) обходного пути - вместо того, чтобы повернуть время вспять, они просто позволяли внутренним часам работать на половине обычной скорости в течение двух часов ...

vwegert
источник
4

Вы используете .NET Framework ? Если это так, позвольте мне познакомить вас с типом DateTimeOffset , добавленным в .NET 3.5.

Эта структура содержит DateTimeи смещение (TimeSpan ), который определяет разницу между DateTimeOffsetдатой и временем экземпляра и всемирным координированным временем (UTC).

  • DateTimeOffset.NowСтатический метод возвращает DateTimeOffset экземпляр , состоящий из текущего (локального) времени, а также локальное смещение (как определено в региональной информации операционной системы).

  • DateTimeOffset.UtcNowСтатический метод вернет DateTimeOffset экземпляр , состоящий из текущего времени в UTC (как если бы вы были в Гринвиче).

Другими полезными типами являются классы TimeZone и TimeZoneInfo .

М.А. Ханин
источник
Это не решение представленной проблемы.
caradrye
4

Для тех, кто борется с этим в .NET , посмотрите , стоит ли его использовать DateTimeOffsetи / или TimeZoneInfoстоит ли оно того.

Если вы хотите использовать часовые пояса IANA / Olson или считаете , что встроенные типы не соответствуют вашим потребностям, обратитесь к Noda Time , которая предлагает гораздо более интеллектуальный API даты и времени для .NET.

Мэтт Джонсон
источник
4

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

Внутренне, храните временные метки во что-то вроде гражданского времени-секунд-от-эпохи. Эпоха не имеет значения , в частности , (я предпочитаю эпоху Unix ) , но он делает вещи проще , чем альтернатива. Представьте, что високосных секунд не существует, если вы не делаете что-то, в чем они действительно нуждаются (например, отслеживание спутников). Отображение между временными метками и отображаемым временем является единственной точкой, где должны применяться правила летнего времени; правила часто меняются (на глобальном уровне, несколько раз в год; обвиняют политиков), поэтому вам следует убедиться, что вы не жестко закодировали сопоставление. ОлсонаБаза данных TZ бесценна.

Basil Bourque
источник
3
Проблема здесь заключается в том, что гражданское время (также известное как календарное время) не представляет должным образом ни одного момента времени. Если вы используете подход «секунды из эпохи», действительно ли вы будете учитывать каждый пропущенный или перемотанный момент перехода на летнее время? Возможно нет. Базис эпохи работает только против UTC или другого фиксированного эталона с мгновенным временем.
Мэтт Джонсон-Пинт
@MattJohnson Отсюда и часть «бизнес-правил». Если в правилах говорится, что что-то происходит в 2:30 утра (или в любое другое время), это произойдет дважды в один день в году и никогда в один день в году. Это то, что ожидает клиент, если не уточнит правило.
user253751
Хранение внутренних временных меток в гражданском времени может быть очень сложным. Говоря о секундах, потому что эпоха еще сложнее, я бы сказал, что это опасно. Я уверен, что есть люди, которые делают это, и, возможно, можно будет заставить его работать должным образом большую часть времени, если вы будете очень осторожны, но это не может считаться лучшей практикой или общей рекомендацией.
Стив Саммит
2

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

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

Для (почти) всех практических вычислительных целей UTC фактически является GMT. Если вы не видите метки времени с долей секунды, вы имеете дело с GMT, что делает это различие избыточным.

Включите местное смещение времени как есть (включая смещение DST) при сохранении временных меток.

Временная метка всегда представлена ​​в GMT и поэтому не имеет смещения.

Аликс Аксель
источник
1
Смещение по местному времени позволит вам воссоздать первоначальное «настенное время» события. Если вы не сохраните это дополнительное поле, эти данные будут потеряны.
nogridbag
Да, кроме смещения UTC и GMT обратные. Например, UTC-0700 совпадает с GMT + 0700. Действительно, все цифровое оборудование должно использовать UTC в эти дни.
Мэтт Джонсон-Пинт
1
@Matt: вы уверены, что смещения UTC и GMT обратные? где я могу прочитать об этом?
Reto Höhener
На самом деле, я думаю, что раньше я ошибался. GMT и UTC сами по себе не инвертированы. Дело в том, что есть реализации, которые показывают их в обратном порядке, такие как база данных IANA / Olson / TZDB. Смотрите здесь . Другая область, которую вы видите смещением в обратном направлении, находится в функции getTimezoneOffset () javascript.
Мэтт Джонсон-Пинт
@MattJohnson: Это взломы и должны быть отменены.
Аликс Аксель
2

Вот мой опыт: -

(Не требует какой-либо сторонней библиотеки)

  • На стороне сервера сохраняйте время в формате UTC, чтобы все значения даты / времени в базе данных были в одном стандарте независимо от местоположения пользователей, серверов, часовых поясов или летнего времени.
  • На уровне пользовательского интерфейса или в электронных письмах, отправляемых пользователю, вам нужно показывать время в соответствии с пользователем. В этом отношении вам нужно иметь смещение часового пояса пользователя, чтобы вы могли добавить это смещение к значению UTC вашей базы данных, что приведет к локальному времени пользователя. Вы можете либо принять смещение часового пояса пользователя, когда они регистрируются, либо вы можете автоматически определять его на веб-и мобильных платформах. Для веб-сайтов метод JavaScript getTimezoneOffset () является стандартом начиная с версии 1.0 и совместим со всеми браузерами. (Ссылка: http://www.w3schools.com/jsref/jsref_getTimezoneOffset.asp )
доктор
источник
Это не работает, если учесть изменения летнего времени. getTimezoneOffsetвозвращает смещение для даты и времени, когда вы вызываете его. Это смещение может изменяться при переходе часового пояса в летнее время или из него. Смотрите "часовой пояс! = Смещение" в теге часового пояса вики .
Мэтт Джонсон-Пинт
1
Если вы хотите сохранить будильник, например «сделать что-то в 10:00», вы не можете сохранить его в UTC из-за сдвигов DST. Вы должны хранить его относительно местного времени.
Алекс
2

Видео Тома Скотта о часовых поясах на YouTube на канале Computerphile также содержит приятное и занимательное описание темы. Примеры включают в себя:

  • Самоа (остров в Тихом океане) сместил свой часовой пояс на 24 часа вперед, чтобы упростить торговлю с Австралией и Новой Зеландией,
  • Западный берег , где 2 населения следуют за разными часовыми поясами,
  • 18 век переходит от юлианского календаря к григорианскому календарю (что произошло в 20 веке в России).
Аттила Таньи
источник
1

На самом деле kernel32.dll не экспортирует SystemTimeToTzSpecificLocation. Однако он экспортирует следующие два: SystemTimeToTzSpecificLocalTime и TzSpecificLocalTimeToSystemTime ...

штифтик
источник
1

Никогда не полагайтесь только на конструкторов, таких как

 new DateTime(int year, int month, int day, int hour, int minute, TimeZone timezone)

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

Sebi
источник
1

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

Несколько лет назад операционная система Android использовала спутники GPS для получения эталона времени UTC, но игнорировала тот факт, что спутники GPS не используют високосные секунды. Никто не заметил, пока в канун Нового года не было путаницы, когда пользователи телефонов Apple и Android-телефонов делали обратный отсчет с интервалом около 15 секунд.

Я думаю, что с тех пор это было исправлено, но вы никогда не знаете, когда эти «мелкие детали» снова будут преследовать вас.

DavidWalley
источник
1
  • Никогда, никогда не храните местное время без смещения UTC (или ссылки на часовой пояс) - примеры того, как этого не делать, включают FAT32 и struct tm в C. in
  • Поймите, что часовой пояс представляет собой комбинацию
    • набор смещений UTC (например, +0100 зимой, +0200 летом)
    • правила, когда происходит переключение (которое может меняться со временем: например, в 1990-х годах ЕС согласовал переключение на последние воскресенья марта и октября в 02:00 по стандартному времени / 03:00 по летнему времени; ранее это отличалось между государствами-членами).

¹ Некоторые реализации struct tmхранят смещение UTC, но это не вошло в стандарт.

user149408
источник
-4

Имея дело с базами данных (в частности, с MySQL , но это относится к большинству баз данных), мне было трудно хранить UTC.

  • Базы данных обычно работают с сервером datetime по умолчанию (то есть CURRENT_TIMESTAMP).
  • Возможно, вы не сможете изменить часовой пояс сервера.
  • Даже если вы можете изменить часовой пояс, у вас может быть сторонний код, который ожидает, что часовой пояс сервера будет локальным.

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

Если у вас есть 100% контроль над сервером и всем кодом, вероятно, лучше изменить часовой пояс сервера на UTC.

MartijnCMT
источник
Местное время (время сервера) может быть неоднозначным при переходе на летнее время в стиле «откат». Это не надежно использовать, как вы описали. Может быть более одного времени UTC, которое может представлять местное время сервера.
Мэтт Джонсон-Пинт
Местное время прекрасно, если сервер находится в нормальном часовом поясе, то есть в том, который не использует DST.
Сап