How to change time zone settings using windows api

2019-05-10 22:03发布

问题:

I need to change DST and time zone via API in my application. I modified & copied example of "SetTimeZoneInformation" usage by the end of the following link and have run it: http://msdn.microsoft.com/en-us/library/windows/desktop/ms724944(v=vs.85).aspx

I am assuming that my time settings should reflect on my time settings in tray or control panel. But nothing happens.

Following thing also should be noticed.

This code modifies "HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation" key content. And there are no changes in "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\my time zone" thread. But this is what I am looking for!

Is there any way to modify "my time zone" using API in C++?

Added (from the answer that should have been edited in here):

So, actually, my goal is to make my application to work under Win7. Existing functionality uses MANUAL DST support. Thus, I need somehow synchronize this manual DST and GMT offset settings with Win7 ones. As I understood, SetTimeZoneInformation function just tries something like to find time zone from the existing set of time zones according to my input. If there is no time zone equal my input, Win7 uses default one, UTC-12 for instance, and notifies user that "current time zone is not recognized".

So, what approach should I use to realize that?

回答1:

Assuming your code is running with the required privileges and SetTimeZoneInformation() did not return FALSE for another reason, then it did change the system's time zone.

However, the clock applet in the notification area does not know about that change, because you forgot to advertise it in the first place. Quoth the Remarks section of the documentation:

To inform Explorer that the time zone has changed, send the WM_SETTINGCHANGE message.

So, you should broadcast a WM_SETTINGCHANGE message to all the top-levels windows when your application changes the system's time zone. Something like:

SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, NULL, NULL,
    SMTO_NORMAL, aShortTimeoutInMilliseconds, NULL);


回答2:

Did you check the return codes for error? See the following from the linked page:

An application must have the SE_TIME_ZONE_NAME privilege for this function to succeed. This privilege is disabled by default. Use the AdjustTokenPrivileges function to enable the privilege before calling SetTimeZoneInformation, and then to disable the privilege after the SetTimeZoneInformation call. For more information, see Running with Special Privileges.

plus, send WM_SETTINGCHANGE as a broadcast message to notify the "tray" (SNA) about the change.

I know the sample code tries to enable the privilege, but it does no error checking and goes forth to call SetTimeZoneInformation anyway ...



标签: c++ time dst zone