Включить и отключить DST в ОС Windows по коду - PullRequest
0 голосов
/ 11 апреля 2019

Есть ли способ включить и отключить DST (летнее время) в ОС Windows по коду?

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

Также я пытался изменить свойство Bias структуры DYNAMIC_TIME_ZONE_INFORMATION, это позволяет мне изменять дату и время, но не включать и не отключать DST ...

Есть ли способ решить эту проблему?

Следующий исходный код отключает только DST, но мне нужно включить снова ...

    OpenProcessToken(::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);

    TOKEN_PRIVILEGES tp;
    LookupPrivilegeValue(NULL, SE_TIME_ZONE_NAME, &tp.Privileges[0].Luid);
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    AdjustTokenPrivileges(hToken, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0);

    DYNAMIC_TIME_ZONE_INFORMATION dyTimeZoneInfo;
    ZeroMemory(&dyTimeZoneInfo, sizeof(dyTimeZoneInfo));
    DWORD tzId = GetDynamicTimeZoneInformation(&dyTimeZoneInfo);

    dyTimeZoneInfo.DynamicDaylightTimeDisabled = !dyTimeZoneInfo.DynamicDaylightTimeDisabled;
    dyTimeZoneInfo.DaylightBias = 0;
    dyTimeZoneInfo.StandardDate.wDay = 0;
    dyTimeZoneInfo.StandardDate.wDayOfWeek = 0;
    dyTimeZoneInfo.StandardDate.wHour = 0;
    dyTimeZoneInfo.StandardDate.wMilliseconds = 0;
    dyTimeZoneInfo.StandardDate.wMinute = 0;
    dyTimeZoneInfo.StandardDate.wMonth = 0;
    dyTimeZoneInfo.StandardDate.wSecond = 0;
    dyTimeZoneInfo.StandardDate.wYear = 0;

    dyTimeZoneInfo.DaylightDate.wDay = 0;
    dyTimeZoneInfo.DaylightDate.wDayOfWeek = 0;
    dyTimeZoneInfo.DaylightDate.wHour = 0;
    dyTimeZoneInfo.DaylightDate.wMilliseconds = 0;
    dyTimeZoneInfo.DaylightDate.wMinute = 0;
    dyTimeZoneInfo.DaylightDate.wMonth = 0;
    dyTimeZoneInfo.DaylightDate.wSecond = 0;
    dyTimeZoneInfo.DaylightDate.wYear = 0;

    SetDynamicTimeZoneInformation(&dyTimeZoneInfo);

    tp.Privileges[0].Attributes = NULL;
    AdjustTokenPrivileges(hToken, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0);

    CloseHandle(hToken);

Буду признателен за любую помощь.

Ответы [ 2 ]

0 голосов
/ 12 апреля 2019

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

dyTimeZoneInfo.DynamicDaylightTimeDisabled = !dyTimeZoneInfo.DynamicDaylightTimeDisabled;

То, что включает функцию автоматического перехода на летнее время, в то время как остальная часть вашего кода строго отключает ее. Вместо этого установите значение true.

dyTimeZoneInfo.DynamicDaylightTimeDisabled = TRUE;

Для повторного включения DST вам необходимо восстановить исходные значения полей DaylightBias, DaylightStart и StandardStart. (Не думайте, что DaylightBias всегда равно -60, хотя бы один равен -30.)

Лучше всего восстановить всю структуру DYNAMIC_TIME_ZONE_INFORMATION. Чтобы сделать это, используйте функцию EnumDynamicTimeZoneInformation, чтобы перебрать все часовые пояса в системе и выбрать тот, где TimeZoneKeyName соответствует текущему.

Наконец, вы можете подумать, зачем вам это вообще нужно делать. Отключение DST через этот механизм обычно больше не требуется. Это устаревшая особенность. Есть соответствующие записи часового пояса для всего мира, включая районы без DST. Если вы просто пытаетесь эмулировать настройки операционной системы в своем собственном приложении (возможно, в приложении для управления системой), тогда все в порядке. Но для большинства других целей вам не нужно манипулировать этим параметром.

0 голосов
/ 11 апреля 2019

Этот исходный код решает мою проблему.

    HANDLE hToken;
    OpenProcessToken(::GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken);

    TOKEN_PRIVILEGES tp;
    LookupPrivilegeValue(NULL, SE_TIME_ZONE_NAME, &tp.Privileges[0].Luid);
    tp.PrivilegeCount = 1;
    tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
    AdjustTokenPrivileges(hToken, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0);

    DYNAMIC_TIME_ZONE_INFORMATION dyTimeZoneInfo;
    ZeroMemory(&dyTimeZoneInfo, sizeof(dyTimeZoneInfo));
    DWORD tzId = GetDynamicTimeZoneInformation(&dyTimeZoneInfo);

    dyTimeZoneInfo.DynamicDaylightTimeDisabled = !dyTimeZoneInfo.DynamicDaylightTimeDisabled;

    if (dyTimeZoneInfo.DynamicDaylightTimeDisabled)
        dyTimeZoneInfo.Bias = dyTimeZoneInfo.StandardBias;
    else
        dyTimeZoneInfo.Bias = dyTimeZoneInfo.DaylightBias;

    SetDynamicTimeZoneInformation(&dyTimeZoneInfo);

    tp.Privileges[0].Attributes = NULL;
    AdjustTokenPrivileges(hToken, FALSE, &tp, 0, (PTOKEN_PRIVILEGES)NULL, 0);

    CloseHandle(hToken);
...