Click here to Skip to main content
15,881,380 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.9K   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

 
GeneralSimpleTimeZone class for .net Pin
ninj18-Oct-04 23:56
ninj18-Oct-04 23:56 
GeneralA couple of bugs Pin
Eric Woodruff9-Oct-04 20:38
professionalEric Woodruff9-Oct-04 20:38 
GeneralRe: A couple of bugs Pin
Joe Woodbury10-Oct-04 8:35
professionalJoe Woodbury10-Oct-04 8:35 
QuestionCan you convert to VB.NET? Pin
Hugo G6-Oct-04 4:12
Hugo G6-Oct-04 4:12 
AnswerRe: Can you convert to VB.NET? Pin
Joe Woodbury10-Oct-04 8:57
professionalJoe Woodbury10-Oct-04 8:57 
GeneralRe: Can you convert to VB.NET? Pin
Hugo G11-Oct-04 0:31
Hugo G11-Oct-04 0:31 
GeneralRe: Can you convert to VB.NET? Pin
Joe Woodbury11-Oct-04 4:36
professionalJoe Woodbury11-Oct-04 4:36 
GeneralRe: Can you convert to VB.NET? Pin
Anna-Jayne Metcalfe6-Sep-05 1:05
Anna-Jayne Metcalfe6-Sep-05 1:05 
GeneralRe: Can you convert to VB.NET? Pin
Anna-Jayne Metcalfe28-Mar-06 7:37
Anna-Jayne Metcalfe28-Mar-06 7:37 
GeneralRe: Can you convert to VB.NET? Pin
MT9999928-Mar-06 7:40
MT9999928-Mar-06 7:40 
QuestionMy fault ? Pin
Colin Urquhart26-Sep-04 20:08
Colin Urquhart26-Sep-04 20:08 
GeneralGetNthDayOfWeek problem Pin
Colin Urquhart22-Sep-04 20:45
Colin Urquhart22-Sep-04 20:45 
GeneralRe: GetNthDayOfWeek problem Pin
Joe Woodbury23-Sep-04 9:25
professionalJoe Woodbury23-Sep-04 9:25 
GeneralRe: GetNthDayOfWeek problem Pin
Colin Urquhart23-Sep-04 13:14
Colin Urquhart23-Sep-04 13:14 
GeneralRe: GetNthDayOfWeek problem Pin
Colin Urquhart23-Sep-04 13:23
Colin Urquhart23-Sep-04 13:23 
GeneralRe: GetNthDayOfWeek workaround Pin
Colin Urquhart23-Sep-04 19:02
Colin Urquhart23-Sep-04 19:02 
GeneralRe: GetNthDayOfWeek workaround Pin
Joe Woodbury23-Sep-04 19:17
professionalJoe Woodbury23-Sep-04 19:17 
GeneralRe: GetNthDayOfWeek workaround Pin
Colin Urquhart23-Sep-04 19:47
Colin Urquhart23-Sep-04 19:47 
GeneralPlease, respect other people's work and don't point out to pay-per-view urls Pin
Luca Piergentili23-Jun-03 21:03
Luca Piergentili23-Jun-03 21:03 
GeneralRe: Please, respect other people's work and don't point out to pay-per-view urls Pin
nsimeonov4-Dec-03 5:43
nsimeonov4-Dec-03 5:43 
GeneralWill definitely NOT work in VC 6.0 Pin
WREY22-Jun-03 11:13
WREY22-Jun-03 11:13 
GeneralRe: Will definitely NOT work in VC 6.0 Pin
Anna-Jayne Metcalfe6-Sep-05 0:55
Anna-Jayne Metcalfe6-Sep-05 0:55 
GeneralWindows Supplies TimeZone Info Pin
John Carson20-Jun-03 22:46
John Carson20-Jun-03 22:46 

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.