English 中文(简体)
我怎样在Win32中获得一个特定的TIME_ZONE_INFORMATION结构体?
原标题:
  • 时间:2009-01-21 16:55:36
  •  标签:

Win32的GetTimeZoneInformation函数将返回控制面板中设置的系统本地时区。我怎样获取其他特定的时区?是否有相应的调用方法?

托尼

最佳回答

根据这个链接中所述,不同时区的信息存储在注册表中,因此您需要从那里检索信息并自己填充TIME_ZONE_INFORMATION结构。

从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
问题回答

代码

#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
");
        return -1;
    }

    if (ERROR_SUCCESS != (dw = RegOpenKey(HKEY_LOCAL_MACHINE, tzsubkey, &hkey_tz))) {
        fprintf(stderr, "failed to open: HKEY_LOCAL_MACHINE\%s
", 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
", 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
", ut.wYear, ut.wMonth, ut.wDay, ut.wHour, ut.wMinute, ut.wSecond);
    printf("=
");
    printf("%d-%02d-%02d %02d:%02d:%02d Europe/Moscow
", lt.wYear, lt.wMonth, lt.wDay, lt.wHour, lt.wMinute, lt.wSecond);
    return 0;
}




相关问题
热门标签