按代码在Windows操作系统上启用和禁用DST

问题描述 投票:-1回答:2

有没有办法在Windows操作系统上按代码启用和禁用DST(夏令时)?

我一直在关注下一个link上提到的步骤,但没有成功......

此外,我一直在尝试更改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);

我会感激任何帮助。

c++ c winapi registry dst
2个回答
0
投票

您的原始代码大多是正确的。我看到的主要问题是:

dyTimeZoneInfo.DynamicDaylightTimeDisabled = !dyTimeZoneInfo.DynamicDaylightTimeDisabled;

这会切换自动DST功能,而其余代码则严格禁用它。而是将其设置为true。

dyTimeZoneInfo.DynamicDaylightTimeDisabled = TRUE;

要重新启用DST,您需要恢复DaylightBiasDaylightStartStandardStart字段的原始值。 (不要假设DaylightBias总是-60,至少有一个是-30。)

最好只是恢复整个DYNAMIC_TIME_ZONE_INFORMATION结构。为此,使用EnumDynamicTimeZoneInformation函数迭代系统上的所有时区,并选择TimeZoneKeyName与当前时区匹配的时区。

最后,您可能想要考虑为什么需要这样做。通常不再需要通过此机制禁用DST。这是一项遗留功能。全世界都有适当的时区条目,包括没有DST的区域。如果您只是想在自己的应用程序(可能是系统管理应用程序)中模拟操作系统的设置,那么很好。但是对于大多数其他目的,您不需要操纵此设置。


-2
投票

这个源代码解决了我的问题。

    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);
© www.soinside.com 2019 - 2024. All rights reserved.