Ответ 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 года.
(щелкните изображение, чтобы увидеть полное разрешение, и обратите внимание на области, отмеченные вручную красным цветом, которые меняются по сравнению с предыдущим годом)
Динамические записи 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. Есть и ряд других жизнеспособных вариантов.