Click here to Skip to main content
Click here to Skip to main content

World Clock and the TimeZoneInformation class

, 3 Jan 2006 Public Domain
Rate this:
Please Sign up or sign in to vote.
Using the operating system's time zone APIs to convert times from Universal time (UTC) to a specified time zone.

Introduction

This article was spurred by discussions on the Channel 9 forums around the time of the daylight changes this year. Some users were complaining that the site was not indicating the posting time accurately. I suggested a route forward but failed to convince the administrators. This article is an attempt to provide code that is useful for converting a time stamp into the end-user's own time zone.

Another group of users also need to deal with the time zones: travelers wishing to know the time at their destination, or the time at home - for example, when trying to call relatives or colleagues. The accompanying application, a demonstration of the TimeZoneInformation class, is useful here. It could also be useful for working out when a Webcast, for example, occurs in your local time zone.

Time zones

Different countries and locations around the world use different time zones - to match the time shown on a clock with the approximate local time observed. The simplest description is an offset from UTC - Universal Time (Coordinated) - although often erroneously described as an offset from GMT - Greenwich Mean Time. GMT can describe the time zone used in Britain, or a specific offset (UTC+0). The issue is complicated by the Daylight Savings Time; some locations observe daylight savings whereas others do not. Even when they do, they do not agree on the dates and times at which the changes to and from Daylight Savings occur.

Keeping an accurate record of the time zones used around the world is a hard task. Local administrations make rules about the local offset from UTC, and about whether to observe daylight savings, and if so, when. Fortunately, Windows has a database of time zone information installed on every system. Unfortunately, Microsoft failed to provide an API for querying this database.

In addition, Windows provides APIs for discovering the currently selected time zone, for converting from UTC to a specified time zone's local time, and (Windows XP and Server 2003 only) for converting from local time, in a specified zone, to UTC.

.NET APIs

.NET's base class library offers the System.TimeZone class. This class offers information about the current time zone. However, it does not offer any information about other time zones - what their names are, their offsets, or their daylight savings rules. This class is abstract, so could be extended. I have not yet done that as some of the features (GetDaylightChanges, IsDaylightSavingTime) will be difficult to implement, due to the apparent lack of OS support. A route of investigation would be to inspect the implementation of System.TimeZone in the Shared Source CLI [^].

The time zone database

Windows NT's time zone database is stored in the registry, at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones. Under this key are the subkeys describing each time zone. Each subkey has the following values (examples taken from the GMT Standard Time key):

Value Type Purpose Example
Display REG_SZ Display name (GMT) Greenwich Mean Time: Dublin, Edinburgh, Lisbon, London
Dlt REG_SZ Name for the zone during daylight savings GMT Daylight Time
Index REG_DWORD Unique index number for zone 85
MapID REG_SZ Unknown. May be related to Win95 clickable time zone map. 0,1
Std REG_SZ Name for the zone outside daylight savings GMT Standard Time
TZI REG_BINARY Offsets and savings start/end date see below

The TZI value is the key part. It contains the offset from UTC, the additional offset for daylight savings, and the start and end dates for daylight savings. The structure is defined as follows:

[StructLayout( LayoutKind.Sequential )]
private struct TZI
{
    public int bias;
    public int standardBias;
    public int daylightBias;
    public SYSTEMTIME standardDate;
    public SYSTEMTIME daylightDate;
}

The bias, standardBias and daylightBias fields follow the rules for the corresponding members of the Win32 TIME_ZONE_INFORMATION structure: UTC = local + bias. A negative value indicates that the zone is ahead of UTC (typically east of London) while a positive one indicates behind UTC (typically west of London).

The TimeZoneInformation class provides access to the time zone database through the EnumZones static method. It exposes an Index property matching the Index registry value. The value of this field could be stored in a database, to persist, for example, a website user's time zone selection. I do not expect this value to change between operating system versions.

Converting times

The operating system provides two APIs for converting times relative to a time zone: SystemTimeToTzSpecificLocalTime and TzSpecificLocalTimeToSystemTime. The former is available only on NT-based operating systems, while the latter is only present on Windows XP and Server 2003 at the time of writing. To use these with a .NET DateTime structure, we must convert the DateTime to a SYSTEMTIME, the TZI to a TIME_ZONE_INFORMATION, and convert the resulting SYSTEMTIME back to a DateTime. DateTime conversions to and from SYSTEMTIME are performed via a FILETIME using the SystemTimeToFileTime and FileTimeToSystemTime APIs.

Mapping a TZI to a TIME_ZONE_INFORMATION is simply a matter of assigning the corresponding fields.

The TimeZoneInformation class converts from UTC to time-zone relative local time using the FromUniversalTime method, and from a time-zone relative local time to UTC using the ToUniversalTime method. This latter method will only work on Windows XP or Windows Server 2003; on down-level operating systems (Windows NT 4.0, Windows 2000) it throws a NotSupportedException.

The sample application

The supplied sample application converts either the current time, or a user-selected date and time, from the user's current time zone (or a selected time zone) to a user-selected time zone. The time zone selection defaults to the user's current time zone, so initially, the destination time will be the same as the current zone.

If the user selects Use Current, the local and the destination time update with the system clock.

If the Time Zone checkbox under Local Time is selected, the corresponding drop-down list can be used to select the time zone to convert from. On Windows 2000 or earlier, if this checkbox is selected, an error message will be displayed and the checkbox is subsequently disabled, reflecting the fact that the feature cannot be supported. The selected date and time are converted from the source time zone to UTC, and then from UTC to the destination zone.

I admit that the user interface is basic! I'm no graphic designer. Nevertheless, I hope it will be useful.

Updates

  • Version 1.2
    • TimeZoneInformation class: A bug-fix was made to the CurrentTimeZone static property to cope with the 'Automatically adjust clock for daylight saving changes' checkbox in the Date and Time control panel applet being unchecked. If this checkbox is unchecked, the GetTimeZoneInformation call returns a structure where DaylightBias and DaylightName are equal to their standard equivalents. This caused the comparison to fail.
    • World clock application: A bug-fix to prevent a crash if no time zone was selected in the Source Zone drop-down when the checkbox was checked.
  • Version 1.1
    • TimeZoneInformation class: The ToUniversalTime method was added to perform conversions to UTC using the TzSpecificLocalTimeToSystemTime API. Other new methods: FromIndex, a static method to locate a TimeZoneInformation object for a recorded Index, and static overloads of FromUniversalTime and ToUniversalTime which take an index argument.
    • World clock application: The Local Time Zone checkbox and drop-down list, allowing the user to specify the zone to convert from.

License

This article, along with any associated source code and files, is licensed under A Public Domain dedication

Share

About the Author

Mike Dimmick
Software Developer (Senior)
United Kingdom United Kingdom
Mike Dimmick is employed as a Software Engineer in the south of England. His role mainly involves Pocket PC programming of Data Capture applications but also encompasses server software and databases, using C++, C#, VB6 and VB.NET. He also leads a double life as a systems administrator.
 
Away from work he enjoys rock music older than he is, reading fiction and playing Xbox.

Comments and Discussions

 
QuestionWindows 8 Unhandled Exception Pinmemberarctuaotcho0815-Oct-14 16:45 
GeneralWindows 7 usage of the TimeZoneInformation.cs class PinmemberTapashya Murali5-Aug-10 1:57 
GeneralBritish Summer Time Pinmemberviaducting24-May-10 4:42 
QuestionReading registry for Time Zones has problem with Vista OS Pinmemberlokeshsp30-Mar-09 23:04 
AnswerRe: Reading registry for Time Zones has problem with Vista OS PinmemberPete Keefe10-Aug-09 7:47 
Questionneed it to run on windows 2K PinmemberZhi Chen12-Feb-09 8:40 
NewsRegistry entries are no longer valid on Windows 2008 PinmemberGrzegorz Lyp19-Jan-09 0:52 
GeneralRe: Registry entries are no longer valid on Windows 2008 Pinmemberrama charan28-Jun-11 5:06 
GeneralCall your code from an outlook addin... PinmemberNaresh Mehta22-Dec-08 0:22 
QuestionCan i add world map PinmemberKrishnraj9-Sep-08 22:01 
GeneralThanks + watch for corrupt timezones in registry PinmemberSteveL122348-Apr-08 20:26 
QuestionTime Convertor Pinmembermnalammwb4-Mar-08 23:16 
GeneralTimeZoneInformation for Windows Mobile (Pocket PCs) Pinmembervbtwo18-Feb-08 11:54 
QuestionDaylight Savings Date Pinmemberjohn.donovan23-Oct-07 4:46 
AnswerRe: Daylight Savings Date Pinmemberb mdtiki26-Oct-07 8:55 
GeneralRe: Daylight Savings Date Pinmemberbj_ray15-Apr-08 9:04 
AnswerRe: Daylight Savings Date Pinmembersdmoore7223-Nov-07 13:17 
GeneralDynamic Daylight Time Zone Information Pinmemberdelowone13-Sep-07 11:56 
GeneralRe: Dynamic Daylight Time Zone Information PinmemberDKN5555511-Oct-07 11:31 
GeneralGreat job! Pinmemberjad_sadah24-Aug-07 1:11 
GeneralBehavior difference in win2003 PinmemberJJMartin24-Jul-07 15:51 
Generalsuperb PinmemberGuy Harwood12-Jun-07 1:40 
GeneralCheckout the new TimeZoneInfo class in .Net Pinmembercrnriman13-May-07 16:56 
GeneralNew class TimeZoneInfo solves all this in .NET 3.5 PinmemberSire40420-May-08 23:28 
QuestionBug - lost precision PinmemberAlex Ivanoff29-Dec-06 12:24 
QuestionTime zone information on Vista Pinmemberbalesteros18-Dec-06 22:28 
AnswerRe: Time zone information on Vista PinmemberAlex Ivanoff29-Dec-06 12:11 
GeneralRe: Time zone information on Vista Pinmemberkulvinder_200014-Feb-07 19:09 
AnswerRe: Time zone information on Vista Pinmemberfuzzylintman22-May-07 11:04 
AnswerRe: Time zone information on Vista PinmemberSnews19-Mar-07 8:49 
QuestionAdding Daylight Change Time [modified] PinmemberAbsalom Komissar (Papu)25-Oct-06 0:23 
Questionutc offset PinmemberdB.1-Oct-06 8:30 
GeneralStandardDate and DaylightDate Pinmemberbumbole24-Jun-06 18:05 
QuestionRe: StandardDate and DaylightDate Pinmemberb mdtiki26-Oct-07 6:08 
GeneralLicensing/use of this code PinmemberMike Dimmick21-Apr-06 13:00 
GeneralRe: Licensing/use of this code PinmemberKing_kLAx9-Sep-06 22:56 
Question2007 Daylight Saving Change PinmemberMunkieFish16-Mar-06 9:47 
AnswerRe: 2007 Daylight Saving Change PinmemberMike Dimmick16-Mar-06 10:34 
AnswerRe: 2007 Daylight Saving Change PinmemberAlex Ivanoff29-Dec-06 12:09 
AnswerRe: 2007 Daylight Saving Change PinmemberStonie31-Jan-07 17:52 
GeneralQuestion about converting UTC time Pinmembermcljava22-Feb-06 13:44 
GeneralRe: Question about converting UTC time PinmemberMike Dimmick22-Feb-06 22:49 
GeneralRe: Question about converting UTC time PinmemberLiamD11-May-06 6:16 
GeneralAdded some properties to the TimeZoneInformation class PinmemberDarren Neimke17-Jan-06 12:04 
Generalrevised 'error in code' message PinmemberBillWoodruff2-Jan-06 3:13 
GeneralRe: revised 'error in code' message PinmemberMike Dimmick4-Jan-06 4:55 
Generalerror in code : comboboxes not set to current time zone PinmemberBillWoodruff2-Jan-06 0:17 
GeneralRe: error in code : comboboxes not set to current time zone PinmemberMike Dimmick2-Jan-06 2:17 
GeneralThanks and a SQL update. Pinmemberstaceyw5-Dec-05 8:44 
GeneralThis was exactly what I needed... PinmemberMattias Olgerfelt25-Oct-05 21:45 

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

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

| Advertise | Privacy | Mobile
Web04 | 2.8.141022.2 | Last Updated 4 Jan 2006
Article Copyright 2004 by Mike Dimmick
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid