2009-01-21 6 views
6

La función Win32 GetTimeZoneInformation devuelve la zona horaria local de su sistema tal como se configuró en el panel de control. ¿Cómo obtengo otra zona horaria específica? Hay una llamada que hace esto?¿Cómo obtengo una estructura TIME_ZONE_INFORMATION específica en Win32?

, Tony

+0

posible duplicado de [? ¿Cómo se obtiene información para una zona de tiempo arbitrario en Windows] (http://stackoverflow.com/questions/3623471/how-do-you-get-info-for-an-arbitrary-time-zone-in-windows) –

+0

Creo que esta pregunta fue hecha casi dos años antes de la otra pregunta. – AnthonyLambert

+0

Los encontré a los dos al mismo tiempo, y la otra pregunta tiene una mejor respuesta. [La edad de la pregunta no importa.] (Http://meta.stackoverflow.com/a/260367/634824) –

Respuesta

5

Según this la información para las diferentes zonas horarias se almacena en el registro, por lo que tendrá que recuperar la información desde allí y poblar el TIME_ZONE_INFORMATION struct mismo.

Cita del artículo de MSDN

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

código:

#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; 
} 
Cuestiones relacionadas