2009-01-21 2 views
6

Die Win32 GetTimeZoneInformation-Funktion gibt die Systemzeitzone zurück, die in der Systemsteuerung eingerichtet wurde. Wie bekomme ich eine andere bestimmte Zeitzone? Gibt es einen Anruf, der das tut?Wie bekomme ich eine bestimmte TIME_ZONE_INFORMATION-Struktur in Win32?

Tony

+0

möglich Duplikat [? Wie Sie Informationen in Windows für eine beliebige Zeitzone erhielten] (http://stackoverflow.com/questions/3623471/how-do-you-get-info-für-eine-arbitrary-time-zone-in-windows) –

+0

Ich denke, diese Frage wurde fast zwei Jahre vor der anderen Frage gestellt. – AnthonyLambert

+0

Ich fand sie beide zur gleichen Zeit, und die andere Frage hat eine bessere Antwort. [Das Alter der Frage spielt keine Rolle.] (Http://meta.stackoverflow.com/a/260367/634824) –

Antwort

5

Nach this die Informationen für die verschiedenen Zeitzonen ist in der Registry gespeichert, so dass Sie die Informationen von dort, und füllen Sie die TIME_ZONE_INFORMATION struct selbst müssen abgerufen werden.

Zitat aus dem MSDN-Artikel

Remarks 

Settings for each time zone are stored in the following registry key: 

HKEY_LOCAL_MACHINE 
    SOFTWARE 
      Microsoft 
       Windows NT 
        CurrentVersion 
         Time Zones 
           time_zone_name
1

Code:

#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, /*WORD wYear;*/ 
     1, /*WORD wMonth;*/ 
     0, /*WORD wDayOfWeek;*/ 
     1, /*WORD wDay;*/ 
     12, /*WORD wHour;*/ 
     0, /*WORD wMinute;*/ 
     0, /*WORD wSecond;*/ 
     0 /*WORD wMilliseconds;*/ 
    }; 
    SystemTimeToTzSpecificLocalTime(&tzi, &ut, &lt); 

    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; 
}