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.
This API contains enumeration for all the World’s time zones, their bias
(offset from UTC), and both the Standard and Daylight labels for the time zones.
What is interesting is that all this information is built into Windows, but it’s
not accessable normally.
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;
}