Click here to Skip to main content
15,860,972 members
Articles / Desktop Programming / MFC
Article

Time zone class and data

Rate me:
Please Sign up or sign in to vote.
4.56/5 (23 votes)
16 Jan 20077 min read 206.5K   5.3K   66   48
An article on a time zone class and time zone data.

Introduction

In mid-2003, someone in the Lounge asked for a list of time zones. I said that I had one, but the data was in a CodeBase/FoxBase file. Chris Maunder asked if I could retrieve that data and submit it to CodeProject. After procrastinating a few weeks, I decided to go ahead and not only extract the data, but to write a program to edit that data.

Of course, the simple project soon got more complex, then I had to move. Finally, almost two months after starting, it's mostly done. I say mostly, since I'm quite sure there are several bugs in the program and plenty of whistles and bells I could add, but it does fulfill the basic requirement of editing the time zone list.

For the curious, the CTimeZone class was written to handle a situation in a client/server project where individual clients were sending data from multiple time zones. This data had to be filtered at the server according to the time-of-day restrictions local to the source of the data. In other words, we had to convert UTC time to local time with daylight saving time [DST] (note that it's saving, not savings) taken into consideration. The Win32 API provides no help in this situation.

CTimeZone

CTimeZone is the core class of the TimeZoneEditor applet. The current incarnation requires MFC, though this could quite easily be modified for your own purposes. I intentionally made all the data members public. To enforce my own conventions, I should have added helper functions, but I wanted to keep the class as flexible as possible.

The class is commented, though not as well as it could be, so I won't bother repeating those comments here, but one difference between this class and the Win32 TIME_ZONE_INFORMATION structure is that I added week to my Date structure, whereas TIME_ZONE_INFORMATION uses the Day data member to specify this.

The enigma

There is an enigma when resolving DST for a given time; when DST ends, the clocks are set back by one hour (i.e. from 2:00 a.m. to 1:00 a.m.) creating an overlap. If your base time for that zone is within this hour, you cannot determine whether it is daylight saving or standard time. CTimeZone solves this by requiring that all times be expressed in standard time. In other words, any time falling within this hour is assumed to be standard time.

(Your clock doesn't have this problem since it's a state machine, so to speak. When DST ends, at the given time you set the clocks back and change the state to standard time simultaneously.)

TimeZoneEditor.exe

TimeZoneEditor is used to edit the time zone data (see below). It is an MFC document/view application with a few dialog boxes. Besides the CTimeZone class, the application uses three other classes that may be of interest to you: CBSortPtrArray, CStringArrayPlus and CEditAlpha.

  • CBSortPtrArray is from a class library I developed years ago for my own use and that of my employers/clients (the "CB" prefix is from a company I used to own). As the name implies, it is a sortable templated collection of pointers. There are other ways I could have accomplished what I was doing, but I already had this available and saw no reason to make more work for myself.
  • CStringArrayPlus is subclassed from MFC's CStringArray. It adds the ability to sort strings, and some parsing functions which aren't used in this application.
  • CEditAlpha is subclassed from MFC's CEdit. It overrides OnChar and prevents anything but the letters A-Z and, optionally, digits, from being entered.

Time zone data

This is probably the most useful item of this article.

The time zone data is contained in two files. TimeZoneData.tzd is a comma delimited file which contains a list of time zones. Each time zone has a 1-4 character identifier and the information related to that time zone. TimeZoneData.tzd.locations is a comma delimited file containing locations and the identifier of which time zone they are in. (There is a many-to-one relationship between the lines of the latter file and the first one.)

Each location is a country, state, province, territory or island. If the location is part of a country, a comma and the country are added. If the location is a subset of a larger location, a compass direction or a descriptive word is added in parenthesis (i.e. "Saskatchewan (Lloydminster), Canada"). In general, if the vast bulk of the rest of the location falls within a different time zone, no indicator is given (i.e. "Saskatchewan, Canada").

Due to the aforementioned enigma, the end of DST (or "start" of standard time) will be one hour earlier than stated in the rule.

Notes

I started working on TimeZoneEditor with Visual Studio .NET (2002) and finished with VS.NET 2003. The CTimeZone class was originally written using Visual Studio 6.0 and should work with it, but the rest of the app will not.

Finally, CTimeZone should work with UNICODE, however I have not yet tested it with that configuration.

Changes

While verifying and extending the time zone list, I found a lot of contradictory information. I also found that the time of day the change should be made is hard to find for many locations. In those cases, I have defaulted to use 2:00 a.m..

For more information on time zones, I highly recommend this web site[^]. I discovered this site after I had done most my research and have modified my data to comply with it since it does seem to be most authoritative (in some cases, it actually references a nation's law). However, there is no doubt that locations have changed their laws and/or the various sources are mistaken. Please post any change requests with the subject line "Data Change Request". Include an authoritative reference.

History

  • 25th September, 2004
    • CodeProject member Colin Urquhart found a bug in GetNthDayOfWeek(). After mostly figuring out my own code, I realized there was more than one subtle bug related to this method and GetNextDayOfWeek(). Colin and I figured out the core problem at the same time, and he made a brilliant suggestion for a fix which I implemented with some modifications. So, great thanks to Colin Urquhart. (And if the code still doesn't work, it's his fault.:)
  • 10th October, 2004
    • CodeProject member Eric Woodruff found a bug in CCalcDlg::OnBnClickedCalc() where the day of week was not being set. To avoid the 2038 problem (not that I'll care - I'll be 76 and hopefully long retired), I chose to convert the time to file time and back again using SystemTimeToFileTime() and FileTimeToSystemTime() respectively.
  • 12th October, 2005
    • CodeProject member gooshbob found a bug in CTimeZone::GetDiff() where the daylight saving time bias wasn't being calculated right. A very important note was added about the United States changing the start and end dates of DST.
  • 20th March, 2006
    • In the original code, the method CTimeZone::ConvertTime() would convert from UTC if the pSourceZone parameter was NULL and to UTC if it was the same instance that was passed. This latter case was both confusing and problematic. I have moved this functionality to CTimeZone::ConvertTimeToUTC(). Now, if "local" and "remote" time zones are the same, no conversion will happen. This will break the existing code that depends on the original behavior!
  • 10th December, 2006
    • Data has been updated to reflect the changes for the Energy Policy Act of 2005 which extended DST for the United States. Those Canadian provinces which follow DST, have adopted the same schedule as the United States. Other changes were made for the state of Indiana and several countries.
  • 11th January, 2007
    • Data has been updated. DST Bias now defaults to 60, instead of -60.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Software Developer (Senior)
United States United States
Joe is one of those software engineers with a film degree. His first paid programming job (you think film is a good way to make a living?) was writing games for Apple II's using 6502 assembly. He soon moved to 80x86 assembly, C, C++ (for a long time), C# and then back to C++ with occasional dabbling in C#, Python and other vile languages.

He first wrote software for Windows 3.0 in 1990. Save for some work in Linux, DOS and a mercifully brief foray into OS/2, he has concentrated on designing and writing software for all versions and types of Windows except RT.

Comments and Discussions

 
GeneralDoesn't Work in Windows Vista OS Pin
Cowwolfe4-Jan-08 1:35
Cowwolfe4-Jan-08 1:35 
GeneralNot able to download Pin
CraZyToLearn14-Aug-07 2:25
CraZyToLearn14-Aug-07 2:25 
GeneralRe: Not able to download Pin
Joe Woodbury14-Aug-07 5:46
professionalJoe Woodbury14-Aug-07 5:46 
GeneralTimezone Data Update Pin
jimmy.hollon3-Oct-06 10:07
jimmy.hollon3-Oct-06 10:07 
GeneralRe: Timezone Data Update Pin
Joe Woodbury3-Oct-06 10:35
professionalJoe Woodbury3-Oct-06 10:35 
GeneralRe: Timezone Data Update Pin
Ralf Kuners9-Jan-07 21:34
Ralf Kuners9-Jan-07 21:34 
GeneralRe: Timezone Data Update Pin
Joe Woodbury10-Jan-07 5:07
professionalJoe Woodbury10-Jan-07 5:07 
GeneralRe: Timezone Data Update Pin
Ralf Kuners10-Jan-07 21:03
Ralf Kuners10-Jan-07 21:03 
GeneralDear Joe, I used yours useful CTimeZone class in the product which is proposed to be commercial but Pin
vitsavinov26-Sep-06 2:11
vitsavinov26-Sep-06 2:11 
GeneralRe: Dear Joe, I used yours useful CTimeZone class in the product which is proposed to be commercial but Pin
Joe Woodbury26-Sep-06 4:11
professionalJoe Woodbury26-Sep-06 4:11 
GeneralTimeZone [modified] Pin
patilajit2117-Sep-06 23:12
patilajit2117-Sep-06 23:12 
GeneralRe: TimeZone Pin
Joe Woodbury18-Sep-06 3:58
professionalJoe Woodbury18-Sep-06 3:58 
QuestionHow to create TimeZone instance Pin
Sachin Gedam24-Jul-06 2:14
Sachin Gedam24-Jul-06 2:14 
AnswerRe: How to create TimeZone instance Pin
Joe Woodbury24-Jul-06 8:45
professionalJoe Woodbury24-Jul-06 8:45 
GeneralRe: How to create TimeZone instance Pin
Sachin Gedam24-Jul-06 18:38
Sachin Gedam24-Jul-06 18:38 
GeneralRe: How to create TimeZone instance Pin
Joe Woodbury24-Jul-06 19:34
professionalJoe Woodbury24-Jul-06 19:34 
GeneralRe: How to create TimeZone instance Pin
Sachin Gedam24-Jul-06 20:39
Sachin Gedam24-Jul-06 20:39 
GeneralBug report Pin
vitsavinov17-Mar-06 9:10
vitsavinov17-Mar-06 9:10 
GeneralRe: Bug report Pin
Joe Woodbury20-Mar-06 6:46
professionalJoe Woodbury20-Mar-06 6:46 
GeneralThanks Joe..! The trouble is fixed... Everything works - Pin
Vit Savinov1-Apr-06 3:27
Vit Savinov1-Apr-06 3:27 
GeneralWith the upcoming changes in DST... Pin
jkoorr126-Oct-05 3:28
jkoorr126-Oct-05 3:28 
QuestionLatest version? Pin
gooshbob12-Oct-05 11:17
gooshbob12-Oct-05 11:17 
AnswerRe: Latest version? Pin
Joe Woodbury12-Oct-05 12:26
professionalJoe Woodbury12-Oct-05 12:26 
GeneralLeap year bug in GetDaysInMonth Pin
Jeroen Walter15-Dec-04 21:48
Jeroen Walter15-Dec-04 21:48 
GeneralRe: Leap year bug in GetDaysInMonth Pin
Joe Woodbury16-Dec-04 4:07
professionalJoe Woodbury16-Dec-04 4:07 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.