Click here to Skip to main content
15,867,756 members
Articles / Programming Languages / C#
Article

World Clock and the TimeZoneInformation class

Rate me:
Please Sign up or sign in to vote.
4.94/5 (65 votes)
3 Jan 2006Public Domain6 min read 400.6K   7.6K   105   77
Using the operating system's time zone APIs to convert times from Universal time (UTC) to a specified time zone.

Image 1

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):

ValueTypePurposeExample
DisplayREG_SZDisplay name(GMT) Greenwich Mean Time: Dublin, Edinburgh, Lisbon, London
DltREG_SZName for the zone during daylight savingsGMT Daylight Time
IndexREG_DWORDUnique index number for zone85
MapIDREG_SZUnknown. May be related to Win95 clickable time zone map.0,1
StdREG_SZName for the zone outside daylight savingsGMT Standard Time
TZIREG_BINARYOffsets and savings start/end datesee 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:

C#
[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


Written By
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 Pin
arctuaotcho0815-Oct-14 16:45
arctuaotcho0815-Oct-14 16:45 
GeneralWindows 7 usage of the TimeZoneInformation.cs class Pin
Tapashya Murali5-Aug-10 1:57
Tapashya Murali5-Aug-10 1:57 
GeneralBritish Summer Time Pin
hairy_hats24-May-10 4:42
hairy_hats24-May-10 4:42 
QuestionReading registry for Time Zones has problem with Vista OS Pin
lokeshsp30-Mar-09 23:04
lokeshsp30-Mar-09 23:04 
AnswerRe: Reading registry for Time Zones has problem with Vista OS Pin
Pete Keefe10-Aug-09 7:47
Pete Keefe10-Aug-09 7:47 
Questionneed it to run on windows 2K Pin
Zhi Chen12-Feb-09 8:40
Zhi Chen12-Feb-09 8:40 
NewsRegistry entries are no longer valid on Windows 2008 Pin
Grzegorz Łyp19-Jan-09 0:52
Grzegorz Łyp19-Jan-09 0:52 
GeneralRe: Registry entries are no longer valid on Windows 2008 Pin
rama charan28-Jun-11 5:06
rama charan28-Jun-11 5:06 
GeneralCall your code from an outlook addin... Pin
Naresh Mehta22-Dec-08 0:22
Naresh Mehta22-Dec-08 0:22 
QuestionCan i add world map Pin
Krishnraj9-Sep-08 22:01
Krishnraj9-Sep-08 22:01 
Hi,

Can i add World map in my form like Time zone tab available in windows XP os in which if i select any time, the world map shows the location according to that.

Thanks in advance

Krishnraj

GeneralWorks in Windows 2003, but not 2008 or Vista Pin
snataw14-Aug-08 23:59
snataw14-Aug-08 23:59 
GeneralRe: Works in Windows 2003, but not 2008 or Vista Pin
nmirandaghn25-Aug-08 15:10
nmirandaghn25-Aug-08 15:10 
GeneralThanks + watch for corrupt timezones in registry Pin
SteveL122348-Apr-08 20:26
SteveL122348-Apr-08 20:26 
QuestionTime Convertor Pin
mnalammwb4-Mar-08 23:16
mnalammwb4-Mar-08 23:16 
GeneralTimeZoneInformation for Windows Mobile (Pocket PCs) Pin
vbtwo18-Feb-08 11:54
vbtwo18-Feb-08 11:54 
QuestionDaylight Savings Date Pin
john.donovan23-Oct-07 4:46
john.donovan23-Oct-07 4:46 
AnswerRe: Daylight Savings Date Pin
b mdtiki26-Oct-07 8:55
b mdtiki26-Oct-07 8:55 
GeneralRe: Daylight Savings Date Pin
bj_ray15-Apr-08 9:04
bj_ray15-Apr-08 9:04 
AnswerRe: Daylight Savings Date Pin
sdmoore7223-Nov-07 13:17
sdmoore7223-Nov-07 13:17 
GeneralDynamic Daylight Time Zone Information Pin
delowone13-Sep-07 11:56
delowone13-Sep-07 11:56 
GeneralRe: Dynamic Daylight Time Zone Information Pin
DKN5555511-Oct-07 11:31
DKN5555511-Oct-07 11:31 
GeneralGreat job! Pin
jadsadah24-Aug-07 1:11
jadsadah24-Aug-07 1:11 
GeneralBehavior difference in win2003 Pin
JJMartin24-Jul-07 15:51
JJMartin24-Jul-07 15:51 
Generalsuperb Pin
Guy Harwood12-Jun-07 1:40
Guy Harwood12-Jun-07 1:40 
GeneralCheckout the new TimeZoneInfo class in .Net Pin
crnriman13-May-07 16:56
crnriman13-May-07 16:56 

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.