Reputation: 22307
I'm writing a software that allows to change the current time zone parameters used in Windows:
So far the only reference to setting a system-wide time zone that I found is the SetTimeZoneInformation
API (or its variation SetDynamicTimeZoneInformation
.) But I'm not really sure how I can use it to change the current time zone?
For instance, it takes TIME_ZONE_INFORMATION struct with all kinds of information about local time offset, daylight saving settings, etc. I don't understand why do I need to fill all of this info out when all I want to do is, say change the current time zone from "(UTC-08:00) Pacific Time (US & Canada)"
to "(UTC-07:00) Mountain Time (US & Canada)"
.
Am I looking at the correct API to do that?
Upvotes: 2
Views: 2160
Reputation: 22307
It's been a while, so let me try to recap what I ended up doing. Unfortunately my solution was OS specific:
For Windows Vista & later:
Set SE_TIME_ZONE_NAME
privilege.
Call SetDynamicTimeZoneInformation
by specifying the details of the time zone to set.
Remove SE_TIME_ZONE_NAME
privilege.
For Windows XP:
Set SE_SYSTEMTIME_NAME
privilege.
Call SetTimeZoneInformation
with information about the time zone to set.
Reset SE_SYSTEMTIME_NAME
privilege back.
Lastly for both OS, broadcast the following message to let running applications know that the time zone has changed:
::SendMessageTimeout(HWND_BROADCAST, WM_SETTINGCHANGE, 0, (LPARAM)L"intl",
SMTO_ABORTIFHUNG,
2 * 1000, //the total wait time can be up to the value of uTimeout multiplied by the number of top-level windows.
NULL);
PS. To get the information on the current time zone use GetDynamicTimeZoneInformation
or GetTimeZoneInformation
for WinXP.
Additionally you may want to retrieve the list of all available timezones that you may use to choose the info for the new (default) timezone. You can get it from enumerating/parsing the following registry key:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones
Check here and here for the information on its structure.
Upvotes: 1
Reputation: 241808
Honestly, the easiest way is to just use the tzutil.exe
utility. If you need to do this in Win32 C++, then just call from ShellExecute
. Pass the ID of the time zone, not the display name.
See also my answer for doing this from .NET.
Upvotes: 0