Windows API 没有提供直接得到特定时区信息的功能,Windows 系统中的时区信息存储在注册表中下面的位置:
HKEY_LOCAL_MACHINE
SOFTWARE
Microsoft
Windows NT
CurrentVersion
Time Zones
time_zone_name
下面的代码演示了如何从注册表中枚举时区信息:
- #include <stdio.h>
- #include <windows.h>
-
- #define pWin32Error(dwSysErr, sMsg )
-
- typedef struct _REG_TZI_FORMAT
- {
- LONG Bias;
- LONG StandardBias;
- LONG DaylightBias;
- SYSTEMTIME StandardDate;
- SYSTEMTIME DaylightDate;
- } REG_TZI_FORMAT;
-
- #define REG_TIME_ZONES "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones\\"
- #define REG_TIME_ZONES_LEN (sizeof(REG_TIME_ZONES)-1)
- #define REG_TZ_KEY_MAXLEN (REG_TIME_ZONES_LEN + (sizeof(((TIME_ZONE_INFORMATION*)0)->StandardName)/2) -1)
-
- int GetTimeZoneInformationByName(TIME_ZONE_INFORMATION *ptzi, const char StandardName[]) {
- int rc;
- HKEY hkey_tz;
- DWORD dw;
- REG_TZI_FORMAT regtzi;
- char tzsubkey[REG_TZ_KEY_MAXLEN+1] = REG_TIME_ZONES;
-
- strncpy(tzsubkey + REG_TIME_ZONES_LEN, StandardName, sizeof(tzsubkey) - REG_TIME_ZONES_LEN);
- if (tzsubkey[sizeof(tzsubkey)-1] != 0) {
- fprintf(stderr, "timezone name too long\n");
- return -1;
- }
-
- if (ERROR_SUCCESS != (dw = RegOpenKey(HKEY_LOCAL_MACHINE, tzsubkey, &hkey_tz))) {
- fprintf(stderr, "failed to open: HKEY_LOCAL_MACHINE\\%s\n", tzsubkey);
- pWin32Error(dw, "RegOpenKey() failed");
- return -1;
- }
-
- rc = 0;
- #define X(param, type, var) \
- do if ((dw = sizeof(var)), (ERROR_SUCCESS != (dw = RegGetValueW(hkey_tz, NULL, param, type, NULL, &var, &dw)))) { \
- fprintf(stderr, "failed to read: HKEY_LOCAL_MACHINE\\%s\\%S\n", tzsubkey, param); \
- pWin32Error(dw, "RegGetValue() failed"); \
- rc = -1; \
- goto ennd; \
- } while(0)
- X(L"TZI", RRF_RT_REG_BINARY, regtzi);
- X(L"Std", RRF_RT_REG_SZ, ptzi->StandardName);
- X(L"Dlt", RRF_RT_REG_SZ, ptzi->DaylightName);
- #undef X
- ptzi->Bias = regtzi.Bias;
- ptzi->DaylightBias = regtzi.DaylightBias;
- ptzi->DaylightDate = regtzi.DaylightDate;
- ptzi->StandardBias = regtzi.StandardBias;
- ptzi->StandardDate = regtzi.StandardDate;
- ennd:
- RegCloseKey(hkey_tz);
- return rc;
- }
-
- #define ZONE "Russian Standard Time"
-
- int main(int argc, char* argv[])
- {
- DWORD dw;
- TIME_ZONE_INFORMATION tzi;
- dw = GetTimeZoneInformationByName(&tzi, ZONE);
- if (dw != 0) return 1;
- SYSTEMTIME lt;
- SYSTEMTIME ut = {
- 2000,
- 1,
- 0,
- 1,
- 12,
- 0,
- 0,
- 0
- };
- SystemTimeToTzSpecificLocalTime(&tzi, &ut, <);
-
- printf("%d-%02d-%02d %02d:%02d:%02d UTC\n", ut.wYear, ut.wMonth, ut.wDay, ut.wHour, ut.wMinute, ut.wSecond);
- printf("=\n");
- printf("%d-%02d-%02d %02d:%02d:%02d Europe/Moscow\n", lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinute, lt.wSecond);
- return 0;
- }