-1

Are there any way to enable and disable DST (Daylight Saving Time) on Windows OS by code?

I have been following the steps mentioned on the next link, but without success...

Also I have been trying changing "Bias" property of DYNAMIC_TIME_ZONE_INFORMATION struct, it allows me to change date time, but not to enable or disable DST...

Are there any way to solve this problem?

The next source code only disables DST, nevertheless I need to enable again...

    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);

I will appreciate any kind of help.

Alberto Bricio
  • 402
  • 1
  • 6
  • 22

2 Answers2

0

Your original code is mostly correct. The main problem I see is this:

dyTimeZoneInfo.DynamicDaylightTimeDisabled = !dyTimeZoneInfo.DynamicDaylightTimeDisabled;

That toggles the Automatic DST feature, while the rest of your code is strictly disabling it. Instead, set it to true.

dyTimeZoneInfo.DynamicDaylightTimeDisabled = TRUE;

To re-enable DST, you'll need to recover the original values of DaylightBias, DaylightStart, and StandardStart fields. (Don't assume DaylightBias is always -60, there is at least one that is -30.)

It's best just to recover the entire DYNAMIC_TIME_ZONE_INFORMATION structure. To do that, use the EnumDynamicTimeZoneInformation function to iterate through all of the time zones on the system and chose the one where the TimeZoneKeyName matches the current one.

Lastly, you might want to consider why you need to do this at all. Disabling DST via this mechanism is generally not needed anymore. It's a legacy feature. There are appropriate time zone entries for the entire world, including areas without DST. If you are just trying to emulate the operating system's settings in your own application (perhaps a system management app), then fine. But for most other purposes you shouldn't need to manipulate this setting.

Matt Johnson-Pint
  • 230,703
  • 74
  • 448
  • 575
  • I have been taking a look on `timezoneapi.h` which defines `EnumDynamicTimeZoneInformation`. This function is only supported on Windows 7 and 8. Currently, I am using Windows 10 OS and x64 solution platform. Are there another function to enumerate timezones? – Alberto Bricio Apr 15 '19 at 08:23
  • It's supported on Windows 8 and higher, including Windows 10. You may need to include `Windows.h` also. https://learn.microsoft.com/en-us/windows/desktop/api/timezoneapi/nf-timezoneapi-enumdynamictimezoneinformation – Matt Johnson-Pint Apr 15 '19 at 15:34
  • Hi @Matt Johnson , I have included `Windows.h` and the function `EnumDynamicTimeZoneInformation` is still not found... – Alberto Bricio Apr 16 '19 at 09:07
  • 1
    Steange. Are you using a recent Windows SDK? – Matt Johnson-Pint Apr 16 '19 at 15:02
  • I'm using Windows SDK version 8.1 – Alberto Bricio Apr 16 '19 at 15:18
  • Well, the Windows 10 SDK is [here](https://developer.microsoft.com/en-us/windows/downloads/windows-10-sdk)... Perhaps I'm misunderstanding? – Matt Johnson-Pint Apr 16 '19 at 15:36
  • Hi Matt, thanks for your effort. But, maybe are there any way to solve this without updating Windows SDK? – Alberto Bricio Apr 16 '19 at 15:39
  • What is it that keeps you from using it on Windows 10? You said it was supported for Windows 8. Does the compiled exe then fail on Windows 10? – Matt Johnson-Pint Apr 16 '19 at 16:31
  • FWIW, in the Win 10 SDK on my machine, `timezoneapi.h` has `EnumDynamicTimeZoneInformation` in an ifdef that is: `#if (_WIN32_WINNT >= _WIN32_WINNT_WIN8)` – Matt Johnson-Pint Apr 16 '19 at 17:44
-2

This source code solves my problem.

    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);
Alberto Bricio
  • 402
  • 1
  • 6
  • 22
  • Careful. You're assigning the `StandardBias` and `DaylightBias` to the `Bias` field, but the docs explain that those are the *delta's*. You're overwriting the `Bias` value. See my answer instead. – Matt Johnson-Pint Apr 12 '19 at 17:19