Windows中的时区信息

Windows API 没有提供直接得到特定时区信息的功能,Windows 系统中的时区信息存储在注册表中下面的位置:


HKEY_LOCAL_MACHINE
     SOFTWARE
          Microsoft
               Windows NT
                    CurrentVersion
                         Time Zones
                              time_zone_name

 

下面的代码演示了如何从注册表中枚举时区信息:

 

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
 
  1. #include <stdio.h>  
  2. #include <windows.h>  
  3.   
  4. #define pWin32Error(dwSysErr, sMsg )  
  5.   
  6. typedef struct _REG_TZI_FORMAT  
  7. {  
  8.     LONG Bias;  
  9.     LONG StandardBias;  
  10.     LONG DaylightBias;  
  11.     SYSTEMTIME StandardDate;  
  12.     SYSTEMTIME DaylightDate;  
  13. } REG_TZI_FORMAT;  
  14.   
  15. #define REG_TIME_ZONES "SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Time Zones\\"  
  16. #define REG_TIME_ZONES_LEN (sizeof(REG_TIME_ZONES)-1)  
  17. #define REG_TZ_KEY_MAXLEN (REG_TIME_ZONES_LEN + (sizeof(((TIME_ZONE_INFORMATION*)0)->StandardName)/2) -1)  
  18.   
  19. int GetTimeZoneInformationByName(TIME_ZONE_INFORMATION *ptzi, const char StandardName[]) {  
  20.     int rc;  
  21.     HKEY hkey_tz;  
  22.     DWORD dw;  
  23.     REG_TZI_FORMAT regtzi;  
  24.     char tzsubkey[REG_TZ_KEY_MAXLEN+1] = REG_TIME_ZONES;  
  25.   
  26.     strncpy(tzsubkey + REG_TIME_ZONES_LEN, StandardName, sizeof(tzsubkey) - REG_TIME_ZONES_LEN);  
  27.     if (tzsubkey[sizeof(tzsubkey)-1] != 0) {  
  28.         fprintf(stderr, "timezone name too long\n");  
  29.         return -1;  
  30.     }  
  31.   
  32.     if (ERROR_SUCCESS != (dw = RegOpenKey(HKEY_LOCAL_MACHINE, tzsubkey, &hkey_tz))) {  
  33.         fprintf(stderr, "failed to open: HKEY_LOCAL_MACHINE\\%s\n", tzsubkey);  
  34.         pWin32Error(dw, "RegOpenKey() failed");  
  35.         return -1;  
  36.     }  
  37.   
  38.     rc = 0;  
  39.     #define X(param, type, var) \  
  40.         do if ((dw = sizeof(var)), (ERROR_SUCCESS != (dw = RegGetValueW(hkey_tz, NULL, param, type, NULL, &var, &dw)))) { \  
  41.             fprintf(stderr, "failed to read: HKEY_LOCAL_MACHINE\\%s\\%S\n", tzsubkey, param); \  
  42.             pWin32Error(dw, "RegGetValue() failed"); \  
  43.             rc = -1; \  
  44.             goto ennd; \  
  45.         } while(0)  
  46.     X(L"TZI", RRF_RT_REG_BINARY, regtzi);  
  47.     X(L"Std", RRF_RT_REG_SZ, ptzi->StandardName);  
  48.     X(L"Dlt", RRF_RT_REG_SZ, ptzi->DaylightName);  
  49.     #undef X  
  50.     ptzi->Bias = regtzi.Bias;  
  51.     ptzi->DaylightBias = regtzi.DaylightBias;  
  52.     ptzi->DaylightDate = regtzi.DaylightDate;  
  53.     ptzi->StandardBias = regtzi.StandardBias;  
  54.     ptzi->StandardDate = regtzi.StandardDate;  
  55. ennd:  
  56.     RegCloseKey(hkey_tz);  
  57.     return rc;  
  58. }  
  59.   
  60. #define ZONE "Russian Standard Time"  
  61.   
  62. int main(int argc, char* argv[])  
  63. {  
  64.     DWORD dw;  
  65.     TIME_ZONE_INFORMATION tzi;  
  66.     dw = GetTimeZoneInformationByName(&tzi, ZONE);  
  67.     if (dw != 0) return 1;  
  68.     SYSTEMTIME lt;  
  69.     SYSTEMTIME ut = {  
  70.         2000, /*WORD wYear;*/  
  71.         1, /*WORD wMonth;*/  
  72.         0, /*WORD wDayOfWeek;*/  
  73.         1, /*WORD wDay;*/  
  74.         12, /*WORD wHour;*/  
  75.         0, /*WORD wMinute;*/  
  76.         0, /*WORD wSecond;*/  
  77.         0 /*WORD wMilliseconds;*/  
  78.     };  
  79.     SystemTimeToTzSpecificLocalTime(&tzi, &ut, <);  
  80.   
  81.     printf("%d-%02d-%02d %02d:%02d:%02d UTC\n", ut.wYear, ut.wMonth, ut.wDay, ut.wHour, ut.wMinute, ut.wSecond);  
  82.     printf("=\n");  
  83.     printf("%d-%02d-%02d %02d:%02d:%02d Europe/Moscow\n", lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinute, lt.wSecond);  
  84.     return 0;  
  85. }  

 

posted @ 2014-08-05 23:29  findumars  Views(2339)  Comments(1Edit  收藏  举报