Получение информации о часовом поясе Windows (C++/MFC)

Я пытаюсь:

  1. Получите список названий часовых поясов в том виде, в котором они отображаются, когда пользователь выбирает часовой пояс на панели управления Windows (например, "(UTC-08:00) тихоокеанское время (США и Канада)").

Я делаю это, читая раздел реестра "CurrentVersion\Time Zones", который хорошо работает.

  1. Получить текущий выбранный часовой пояс в виде строки.

Я могу получить текущий часовой пояс, используя GetTimeZoneInformation(), но имена не совпадают со списком часовых поясов, полученным из раздела "CurrentVersion\Time Zones" реестра. Например, в списке часовых поясов тихоокеанское время отображается как "(UTC-08:00) тихоокеанское время (США и Канада)", но GetTimeZoneInformation () содержит строки "Стандартное тихоокеанское время" и "Тихоокеанское летнее время". Мне нужно найти имя, которое соответствует именам "CurrentVersion\Time Zones", чтобы я мог выбрать его из списка.

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

Я могу получить смещение от UTC в timeZoneInformation.Bias, но это только для текущего выбранного часового пояса. Мне нужно знать "предвзятость" из любой зоны, как указано в реестре (например, "(UC-07:00) Горное время (США и Канада)" при настройке перехода на летнее время, если оно действует.

2 ответа

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

В CurrentVersion\Time Zones да - это названия зон.Внутри этого ключа находятся значения для некоторых частей, которые вы хотите.

re: "(UTC-08:00) по тихоокеанскому времени (США и Канада)"

Это в значении реестра "Показать" под названием зоны, которое у вас есть.

В библиотеке ресурсов есть больше строк, определяемых значениями "MUI_Display", "MUI_Std" и "MUI_Dlt". Обычно это что-то вроде "@tzres.dll,-220"

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

Re: Смещение в минутах любого часового пояса.

Также внутри ключа реестра (имя часового пояса) находится значение, называемое "TZI". Это двоичный двоичный объект, который (согласно MSDN) выглядит следующим образом:

typedef struct _REG_TZI_FORMAT
{
    LONG Bias;
    LONG StandardBias;
    LONG DaylightBias;
    SYSTEMTIME StandardDate;
    SYSTEMTIME DaylightDate;
} REG_TZI_FORMAT;

Если различные значения BIAS указаны в минутах, используется уравнение UTC = local + theBias, а theBias - либо Bias + StandardBias, либо Bias + DaylightBias, в зависимости от рассматриваемой даты. Два значения SYSTEMTIME описывают даты перехода.

TimeZoneInfo.Bias

Структура TIME_ZONE_INFORMATION - http://msdn.microsoft.com/en-us/library/windows/desktop/ms725481(v=vs.85).aspx

Функция SetTimeZoneInformation - http://msdn.microsoft.com/en-us/library/windows/desktop/ms724944(v=vs.85).aspx

  // Get the local system time.
SYSTEMTIME LocalTime = { 0 };
GetSystemTime( &LocalTime );

// Get the timezone info.
TIME_ZONE_INFORMATION TimeZoneInfo;
GetTimeZoneInformation( &TimeZoneInfo );

// Convert local time to UTC.
SYSTEMTIME GmtTime = { 0 };
TzSpecificLocalTimeToSystemTime( &TimeZoneInfo,
                                 &LocalTime,
                                 &GmtTime );

// GMT = LocalTime + TimeZoneInfo.Bias
// TimeZoneInfo.Bias is the difference between local time
// and GMT in minutes.

// Local time expressed in terms of GMT bias.
float TimeZoneDifference = -( float(TimeZoneInfo.Bias) / 60 );
CString csLocalTimeInGmt;
csLocalTimeInGmt.Format( _T("%ld:%ld:%ld + %2.1f Hrs"),
                         GmtTime.wHour,
                         GmtTime.wMinute,
                         GmtTime.wSecond,
                         TimeZoneDifference );

Класс TimeZoneInfo - http://msdn.microsoft.com/en-us/library/bb396389 Определить переход на летнее время - http://www.metatrader4.com/forum/2155

Другие вопросы по тегам