A Time Zone API supplement

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



About the Author

Erik Gawtry

I have worked as a Software Engineer since 1985. I currently work with Windows, Unix/Linux, DSP, and Microcontrollers.

Downloads

Comments

  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: May 18, 2015 @ 1:00 p.m. ET / 10:00 a.m. PT While the idea of using facial and or gesture recognitions to create a modern, intuitive game seems attractive, some developers may want to leverage Unity 3D as a way to accelerate their development. There are many different ways in which Intel and Unity Technologies have been working together to helps speed the develop of games with the Intel® RealSense™ SDK (Software Developer Kit), so come hear from a panel of experts on what we've done …

  • Live Event Date: May 6, 2015 @ 1:00 p.m. ET / 10:00 a.m. PT Where are you in your plans to adopt Disaster Recovery-as-a-Service? Are you just getting started? Fighting an uphill battle with management? At Cisco, Zerto and iland, we've seen it all – from the early adopters who excitedly rushed to implement DRaaS with us nine years ago to the IT folks dragging their business leaders into the future. With our years of experience, we've learned there are six types of DRaaS leaders – but which type …

Most Popular Programming Stories

More for Developers

RSS Feeds

Thanks for your registration, follow us on our social networks to keep up-to-date