Безопасен ли часовой пояс Windows, записанный в реестре?

Я создаю проект c++, который должен работать в нескольких часовых поясах. Приложение получает событие с эталонным часовым поясом, и это событие отображается графически пользователю в нужный час в его локальном часовом поясе. Например, пользователь, работающий в Берлине, получает событие, написанное в Токио. Событие из Токио сначала преобразуется в UTC, а затем переводится с UTC на локальное время компьютера в Берлине и, наконец, отображается пользователю на его графическом интерфейсе.

Чтобы конвертировать из UTC в локальное компьютерное время, у меня есть несколько функций API Windows, которыми я располагаю, чтобы выполнить эту работу. Но чтобы преобразовать время из другого часового пояса в UTC, мне нужно получить информацию о часовом поясе из реестра Windows.

Теперь некоторые часовые пояса также имеют время перехода на летнее время. Я могу создать правило повторения из информации Windows без проблем. Однако я заметил, что в день, когда должен произойти DST, иногда бывает некорректно в течение нескольких часовых поясов. Например, "Стандартное время в Южной Америке". С появлением Windows, начальный день DST начинается на 1 неделю раньше.

Если я правильно понял, правило возврата, возвращаемое Windows для этого конкретного часового пояса, говорит "каждый год, во второй месяц, на вторую неделю месяца". Однако это правило редко совпадает с правильной датой, опубликованной в Интернете, для изменения времени, тогда как даты являются правильными, если правило будет "каждый год, на 2-й месяц, на 3-й неделе месяца". Кроме того, как вы можете видеть на приведенном скриншоте, данные реестра Windows показывают 2 недели для времени начала DST (выделено синим цветом), но 3 недели для конечного времени DST (окружено красным), которое правильно вычисляется по моему коду, Описание содержимого данных можно найти здесь: http://msdn.microsoft.com/en-us/library/windows/desktop/ms725481(v=vs.85).aspx

enter image description here

У меня есть несколько вопросов

  • Правильно ли я понял правило повторения? (Вот что говорит MSDN об этом: https://msdn.microsoft.com/en-us/library/windows/desktop/ms725481(v=vs.85).aspx)
  • Известны ли проблемы по нескольким часовым поясам, особенно по "Единому времени в Южной Америке"?
  • Есть ли причина, по которой дата начала летнего времени, которая, очевидно, происходит регулярно каждый год, на третьей неделе 10-го месяца, имеет значение, установленное на 2-й неделе?
  • Является ли часовой пояс, написанный в реестре Windows надежным, если нет, какую функцию Windows API я должен использовать для преобразования часового пояса с DST с даты, написанной в другом часовом поясе, чем тот, который установлен на локальной машине?

ПРИМЕЧАНИЕ. Я строго проверял, были ли данные, которые я прочитал из реестра, были правильными, прежде чем отправлять это сообщение. Я уверен, что это не ошибка такого типа.

ПРИМЕЧАНИЕ. Я работаю с Windows 7, но проблема остается такой же на Windows 10

Ответы

Ответ 1

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

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

Рассмотрим недавний случай Судана, который сообщил 17-21 июня 2017 года список рассылки IANA tz от 1 ноября 2017 года. IANA обработало это изменение, и Microsoft тоже. Но из-за короткого уведомления и времени, необходимого для обработки такого изменения в операционной системе Windows, будет немного, пока не появится новый часовой пояс "Sudan Standard Time" созданный в данных часовых поясов Windows. Таким образом, мы предоставляем временное руководство для использования другого часового пояса на данный момент, а затем возвращаемся назад, когда у нас есть данные, которые должным образом отражают всю историю времени в затронутом регионе.

Что касается часового пояса Windows, о котором вы упомянули, "E. South America Standard Time", данные часового пояса верны. Если вы разберете запись в реестре, вы увидите, что есть под-ключ под названием "Динамический DST", который содержит годовые изменения данных. Для некоторых часовых поясов это вообще не требуется, и для других часовых поясов вы найдете очень маленький объем данных, потому что одно и то же правило повторяется из года в год. Но в случае с Бразилией вы заметите динамические записи DST за 2009 год до 2040 года.

Windows TZ Registry Data

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

Динамические записи DST поддерживают структуру Win32 DYNAMIC_TIME_ZONE_INFORMATION и соответствующие API с "динамическими" в их имени, например GetDynamicTimeZoneInformation. (Они также поддерживают класс System.TimeZoneInfo в.NET Framework.) Большинство этих API были в местах с Windows Vista/Server 2008, а некоторые другие - в Windows 7/Server 2012.

Обратите внимание, что запись TZI которая находится в родительском ключе, копируется из динамического правила текущего года с помощью внутренних процессов Windows. Это поддерживает API, которые работают с структурами Win32 TIME_ZONE_INFORMATION, которые были установлены с Windows 2000.

Чтобы ответить на конкретные вопросы, которые вы задали:

Правильно ли я понял правило повторения?

Конкретное правило, которое вы указали, относится только к 2017 году, и в нем говорится, что DST заканчивается 2-го месяца (февраль), в субботу, 23: 59: 59.999 по местному времени, и начинается снова 10-го месяца (октябрь), по вторая суббота, 23: 59: 59.999 по местному времени. Имейте в виду, что Бразилия находится в южном полушарии, поэтому DST начинается в конце года и заканчивается в начале следующего года.

Кроме того, вы можете задаться вопросом, почему это 23: 59: 59.999 в субботу, а не 00: 00: 00.000 в воскресенье. Это артефакт истории. В прошлом были определенные программы и процессы, которые неправильно использовали <= вместо < чтобы оценить переход, и, таким образом, случайно переместили бы часы на миллисекунду на следующий день, вернемся к нему, а затем снова вернемся к нему. События, порожденные изменением дня, могут затем привести к дальнейшим проблемам. Microsoft сделала все возможное, чтобы исправить эти ошибки, но по-прежнему выбирает 1 мс вместо того, чтобы рискнуть появлением проблемы в каком-то новом месте в один прекрасный день. (Это относится только к переходам, которые происходят точно в полночь.)

Известны ли проблемы по нескольким часовым поясам, особенно по "Единому времени в Южной Америке"?

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

В настоящее время мы также не располагаем часовым поясом, который четко отображает для станции Тролль, Антарктика. Причина в том, что с 2005 по 2015 год эта исследовательская станция (население до 50 лет) переходила через три разных взаимозачета (UTC + 0, UTC + 1 и UTC + 2) каждый год.

Если ваше приложение критически зависит от любого из вышеперечисленных сценариев, я рекомендую использовать API с источниками данных IANA вместо API Win32.

Есть ли причина, по которой дата начала летнего времени, которая, очевидно, происходит регулярно каждый год, на третьей неделе 10-го месяца, имеет значение, установленное на 2-й неделе?

Да, как упоминалось выше, это связано с преднамеренной ошибкой 1мс. DST в 2017 году, в частях Бразилии, которые имеют DST, начинается в воскресенье 15 октября в 00: 00: 00.000. Это третье воскресенье месяца. 1 мс - 23: 59: 59.999 в субботу 14 октября, которая является второй субботой месяца. Это может быть разным с каждым годом, поэтому есть динамические данные DST.

Является ли часовой пояс, написанный в реестре Windows надежным, если нет, какую функцию Windows API я должен использовать для преобразования часового пояса с DST с даты, написанной в другом часовом поясе, чем тот, который установлен на локальной машине?

Если вы используете API Win32, они сами используют данные реестра, поэтому нет необходимости напрямую работать с данными реестра. Вы должны предпочесть "динамические" версии API, поскольку они должным образом учитывают изменения в динамических DST-данных за год. Иногда они обозначаются как "Ex". Например, функция, о которой вы просили, лучше всего обрабатывает функция TzSpecificLocalTimeToSystemTimeEx.

...

Все сказанное, если вы можете избежать использования данных часового пояса Windows в своем приложении, я рекомендую это сделать. Предпочитают источники данных IANA или те, которые получены от них. Существует множество маршрутов для работы с данными часового пояса IANA. Новые API-интерфейсы Windows, такие как Windows.Globalization.Calendar и Windows.Globalization.DatetimeFormatting.DateTimeFormatter в WinRT/UWP действительно используют часовые пояса IANA, и это, безусловно, путь вперед. В стандартном C++ пространстве я настоятельно рекомендую использовать библиотеки даты /tz Говарда Хиннанта или те, которые предоставляются проектом ICU. Есть и ряд других жизнеспособных вариантов.

Ответ 2

Замечательно видеть уровень детализации в сообщении Маттса.

На вопрос "Известны ли проблемы о нескольких часовых поясах, особенно в" Э. Южная Америка Стандартное время "один?"

Нечего добавить больше, кроме того, что Матт невероятно подробный и тщательный вклад в данные о часовых поясах Windows, они проводят тщательную проверку с различными агентствами, НПО и государственными органами, которые были изложены в другом месте. Например, в таких местах, как Марокко, есть дополнительные проблемы, которые не только переходят четыре раза в год, но и информация регулируется правительством, устанавливающим официальное соблюдение ДСТ в регионе, а иногда и с небольшим количеством времени, что приводит к дополнительной публикации и проблемы развертывания. (Не говоря уже о том, что правительство несколько раз пересматривает решение).

Таким образом, для некоторых приложений с критическими зависимостями предпочтительным может быть источник API для IANA или вызов данных часового пояса в Windows. Глобализация.

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