Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you get info for an arbitrary time zone in Windows?

Ideally, what I'd like to be able to do is take the name of a time zone and ask Windows for its corresponding time zone info (offset from UTC, DST offset, dates for DST switch, etc.). It looks like Windows uses a TIME_ZONE_INFORMATION struct to hold this sort of info. So, presumably, I want a function which takes a string with the time zone's name and returns a TIME_ZONE_INFORMATION struct.

However, all I can find are functions such as GetTimeZoneInformation() which give me the TIME_ZONE_INFORMATION for the local time. What I need is a function which will give me that information for an arbitrary time zone regardless of what the local time zone is.

The only way that I see to get that information is to go grab it directly from the registry, which is less than ideal. The TIME_ZONE_INFORMATION page shows where it is in the registry, so it should be possible to fetch the information from there, but I'd much prefer a proper system function for doing it. Does such a function exist, or do I have to go registry diving to get the time zone info for an arbitrary time zone?

like image 583
Jonathan M Davis Avatar asked Sep 02 '10 02:09

Jonathan M Davis


People also ask

How does Windows determine time zone?

The "Set Time Zone Automatically" feature in Windows 10 uses the location information from the Windows Location APIs, which have different levels of accuracy based on where the location information was obtained. Per the documentation on MSDN, the accuracy is as follows: GPS : within approximately 10 meters.

What time zone does Microsoft use?

Microsoft's headquarters are in Washington State, observing PDT (Pacific Daylight-saving Time).


1 Answers

The time zone information is contained as binary data in the registry under HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\(zone name)\TZI. The structure of the data is given in the TIME_ZONE_INFORMATION documentation:

struct STimeZoneFromRegistry
{
 long  Bias;
 long  StandardBias;
 long  DaylightBias;
 SYSTEMTIME StandardDate;
 SYSTEMTIME DaylightDate;
};

And here's example code to read the key:

TIME_ZONE_INFORMATION tz = {0};
STimeZoneFromRegistry binary_data;
DWORD size = sizeof(binary_data);
HKEY hk = NULL;
TCHAR zone_key[] = _T("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones\\Central Standard Time");
if ((RegOpenKeyEx(HKEY_LOCAL_MACHINE, zone_key, 0, KEY_QUERY_VALUE, &hk) == ERROR_SUCCESS) &&
 (RegQueryValueEx(hk, "TZI", NULL, NULL, (BYTE *) &binary_data, &size) == ERROR_SUCCESS))
{
 tz.Bias = binary_data.Bias;
 tz.DaylightBias = binary_data.DaylightBias;
 tz.DaylightDate = binary_data.DaylightDate;
 tz.StandardBias = binary_data.StandardBias;
 tz.StandardDate = binary_data.StandardDate;
}

Edit: Sorry, this answer is redundant - I'm sure you could have figured all this out using the documentation you linked to in the question. I've only had to do this once, and this is the only method I could find.

like image 138
Mark Ransom Avatar answered Oct 25 '22 22:10

Mark Ransom