Часовой пояс не распознан после SetTimeZoneInformation в Windows 10

#c #windows #timezone

#c #Windows #Часовой пояс

Вопрос:

Я пытаюсь изменить часовой пояс в Windows 10, используя Windows API и следуя документации. Я передаю смещение часового пояса, стандартное имя и дневное имя, которые наверняка указаны в реестре в качестве принятых часовых поясов («Стандартное время Центральной Европы» и «Дневное время Центральной Европы»). Часы устанавливаются на правильное время, но когда я открываю настройки часового пояса на панели управления, я вижу сообщение Your current time zone is not recognized. Please select a valid time zone. . Когда я нажимаю на Change time zone кнопку, я вижу, что мой часовой пояс выбран в выпадающем меню, но он не отображается при входе в настройки. Как я могу изменить это или проверить, правильно ли установлен часовой пояс где-нибудь в реестре или что-то еще?

Ответ №1:

Несколько вещей:

  • Не используйте SetTimeZoneInformation , поскольку он не поддерживает полную «динамическую» информацию о часовом поясе, которая используется в современной Windows. Используйте SetDynamicTimeZoneInformation вместо этого. (Документы немного вводят в заблуждение в этом отношении, поскольку это имело место в Windows Vista и новее, а не только в Windows 7 и 8.)

  • Игнорируйте образец в SetTimeZoneInformation документе. Он содержит жестко запрограммированную информацию о смещении часового пояса и информацию о DST. Это не очень хорошая идея. Вместо этого используйте EnumDynamicTimeZoneInformation функцию, чтобы найти зону с желаемым идентификатором в TimeZoneKeyName поле. При обнаружении передайте эту DYNAMIC_TIME_ZONE_INFORMATION структуру SetDynamicTimeZoneInformation функции для изменения часового пояса.

  • Строка "Central Europe Standard Time" — это идентификатор (имя ключа) для часового пояса со следующими строками, локализованными на английском языке, связанными с ним:

    • Отображаемое имя: "(UTC 01:00) Belgrade, Bratislava, Budapest, Ljubljana, Prague"
    • Стандартное имя: "Central Europe Standard Time"
    • Имя дневного света: "Central Europe Daylight Time"
  • Совпадение идентификатора и стандартного английского имени является чисто случайным. Не все часовые пояса Windows совпадают на английском языке, и они, конечно, не будут совпадать, если язык ОС не английский. Не предполагайте, что они будут.

  • Строки "Central Europe Daylight Time" — это не часовой пояс идентификатор. Это просто локализованная понятная строка для названия часового пояса, используемого при действии дневного времени.

  • Поскольку для этого SetDynamicTimeZoneInformation требуется SE_TIME_ZONE_NAME привилегия, возможно, вам будет проще запустить TZUtil.exe утилиту с /s параметром для установки часового пояса по идентификатору. У него уже есть эта привилегия.

Комментарии:

1. спасибо, это сработало! В итоге я использовал комбинацию EnumDynamicTimeZoneInformation и SetDynamicTimeZoneInformation , где я сначала нахожу динамическую информацию о tz на основе стандартного имени и передаю ее установщику. приветствия!

2. просто небольшое редактирование, вы были правы относительно локализации и того, что стандартные и дневные имена переводятся на ваш локальный язык ОС, однако TimeZoneKeyName из DynamicTimezoneInformation используется в качестве ключа и всегда на английском языке, поэтому его можно использовать всегда. 🙂

3. Да, это правильно. Имена ключей всегда являются точными строками (включая любую пунктуацию) и никогда не локализуются. Они поступают из реестра по адресу HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionTime Zones . Это буквально имена разделов реестра.