A Time Zone API supplement
Posted
by Erik Gawtry
on November 30th, 2011
Time Zone API
Unfortunately, the Windows Time Zone API only has four functions:
- GetTimeZoneInformation()
- GetTimeZoneInformationForYear()
- GetDynamicTimeZoneInformation()
- GetDynamicTimeZoneInformationForYear()
These functions only work on the local time zone and, as such, as useless for any globalized application.
Defined Time Zone API Functions:
TZI_LOCALTIMEZONE Defined so that NO TIME ZONE is a valid setting for the Bias. Use this for the bias to indicate that there is no bias and that it is a local time. UINT WINAPI TZIEnum(TIME_ZONE_INFORMATION *pTZI, UINT cbTZI); Get the list of TimeZones Param: TIME_ZONE_INFORMATION pTZI : The Time Zone Infomation array UINT cbTZI : Size of Array to fill Note: Pass NULL and 0 to get the total size needed. Return: UINT : Count of TZI structures enumerated The structures will be filled in in the TZI array void WINAPI FindTimezoneDate(SYSTEMTIME *pEncoded, UINT wYear, SYSTEMTIME *pOut);Decode the encoded SYSTEMTIME Param: SYSTEMTIME *pEncoded : The encoded SYSTEMTIME UINT wYear : Year to work with SYSTEMTIME *pOUT : The decoded SYSTEMTIME Return: None void WINAPI AdjustSystemTime(SYSTEMTIME &stIn, TIME_ZONE_INFORMATION &tzi); Return the updated SYSTEMTIME for the timezone Param: SYSTEMTIME stIn : Time to modify TIME_ZONE_INFORMATION tzi : The Time Zone Infomation block Return: Updated stIn LONG WINAPI GetAdjustSystemTime(SYSTEMTIME &stIn, TIME_ZONE_INFORMATION &tzi); Return the Offset in minutes for the timezone Param: SYSTEMTIME stIn : Time to check TIME_ZONE_INFORMATION tzi : The Time Zone Infomation block Return: LONG : Offset in Minutes BOOL WINAPI IsDST(SYSTEMTIME &stIn, TIME_ZONE_INFORMATION &tzi); Return the DST setting for the timezone Param: SYSTEMTIME stIn : Time to check TIME_ZONE_INFORMATION tzi : The Time Zone Infomation block Return: BOOL : DST setting for the passed time
Sample Code:
/* * Sample program to demonstrate the Time Zone API * * Copyright (c) 2011 Erik H Gawtry */ #include <stdio.h> #include <windows.h> #include <tchar.h> #include "TimeZone.h" #ifndef countof #define countof(a) (sizeof(a)/sizeof(a[0])) #endif int _tmain(int argc, TCHAR *argv[]) { // Get the number of time zones int iCount = (int)TZIEnum(NULL, 0); // Allocate the space TIME_ZONE_INFORMATION *pTZI = (TIME_ZONE_INFORMATION *)malloc(sizeof(TIME_ZONE_INFORMATION)*(iCount+1)); // Zero out ZeroMemory(pTZI, sizeof(TIME_ZONE_INFORMATION)*(iCount+1)); // Get the time zone entries TZIEnum(pTZI, iCount); SYSTEMTIME st, stDaylightDate, stStandardDate; TCHAR szDaylightDate[64], szStandardDate[64]; // Get the UTC system time GetSystemTime(&st); // Loop for(int i = 0; i < iCount; ++i) { // Is it DST? BOOL bDST = IsDST(st, pTZI[i]); // What is the offset LONG lBias = GetAdjustSystemTime(st, pTZI[i]); bool bNegative = (lBias<0); lBias = labs(lBias); // Display the entry with offset _tprintf(_T("%c(%02d:%02d): %-32.32s (%s)"), (bNegative)?'-':'+', lBias/60, lBias%60, bDST?pTZI[i].DaylightName:pTZI[i].StandardName, bDST?_T("DST"):_T(" ST") ); // DST specified for the time zone? if( pTZI[i].DaylightDate.wMonth ) { // Convert to normal time FindTimezoneDate(&pTZI[i].DaylightDate, st.wYear, &stDaylightDate); FindTimezoneDate(&pTZI[i].StandardDate, st.wYear, &stStandardDate); // Format for output GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &stDaylightDate, NULL, szDaylightDate, countof(szDaylightDate)); GetDateFormat(LOCALE_USER_DEFAULT, DATE_SHORTDATE, &stStandardDate, NULL, szStandardDate, countof(szStandardDate)); _tprintf(_T(" %-10.10s %-10.10s"), szDaylightDate, szStandardDate); } _tprintf(_T("\n")); } // Cleanup free(pTZI); return 0; }