I’ve been writing software that allows to change the current time zone parameters used in Windows. This kinda stuff:
The only reference to setting a system-wide time zone that I found was the SetTimeZoneInformation
API (or its variation SetDynamicTimeZoneInformation
.) But I wasn’t 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)"
.
I needed to look further …
The Answer
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.
- Set
- For Windows XP:
- Set
SE_SYSTEMTIME_NAME
privilege. - Call
SetTimeZoneInformation
with information about the time zone to set. - Reset
SE_SYSTEMTIME_NAME
privilege back.
- Set
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);
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