BlackWasp
.NET Framework
.NET 3.5+

Get Time Zone Information

When creating applications that will be used internationally, particularly with a shared database that holds date and time data, it is important to be able to obtain information about time zones. This can be achieved with .NET 3.5's TimeZoneInfo class.

TimeZoneInfo Class

Version 3.5 of the .NET framework introduced a new class named "TimeZoneInfo". Objects of this class provide properties that describe a time zone and methods that can be used to process date and time information in a time zone-specific manner. In this article we will examine how to instantiate a TimeZoneInfo object and interpret its properties.

Retrieving Local Time Zone Information

The TimeZoneInfo class does not provide a public constructor. In order to obtain an instance, you must either read the value of a static property or execute a static method. The first of these that we will use is the Local property. This returns a TimeZoneInfo object that represents the user's local time zone, incorporating the daylight savings time settings that have been applied.

The following code outputs a name for the local time zone to the console. The result will vary according to your computer's configuration:

Console.WriteLine(TimeZoneInfo.Local.DisplayName);

NB: You should always access the properties of the local time zone using the Local property and not assign the values to a variable. This avoids the risk that the variable will become invalid due to changes to the underlying object, specifically by calls to the ClearCachedData method.

TimeZoneInfo Properties

The TimeZoneInfo class provides several properties that describe the time zone. These are:

  • Id. Every time zone has a unique identifier string. This ID can be used when retrieving a TimeZoneInfo object.
  • DisplayName. This property returns a localised display name for the time zone.
  • StandardName. The StandardName property returns a localised display name that describes the time zone during normal times; ie. not during daylight saving time.
  • DaylightName. The DaylightName property returns a string that describes the time zone during daylight saving time periods.
  • BaseUtcOffset. This property returns a TimeSpan structure that represents the time zone's offset from Coordinated Universal Time (UTC). It does not include additional changes due to daylight saving time. A positive value indicates that the local time is ahead of UTC.
  • SupportsDaylightSavingTime. This Boolean property returns true if the time zone supports daylight saving time changes, or false if it does not.

The code below shows the values of the properties for the local time zone for a user in the UK. Results for other time zones may vary.

Console.WriteLine("ID\t{0}", TimeZoneInfo.Local.Id);
Console.WriteLine("Name\t{0}", TimeZoneInfo.Local.DisplayName);
Console.WriteLine("S. Name\t{0}", TimeZoneInfo.Local.StandardName);
Console.WriteLine("D. Name\t{0}", TimeZoneInfo.Local.DaylightName);
Console.WriteLine("Offset\t{0}", TimeZoneInfo.Local.BaseUtcOffset);
Console.WriteLine("DST?\t{0}", TimeZoneInfo.Local.SupportsDaylightSavingTime);

/* OUTPUT

ID      GMT Standard Time
Name    (UTC) Dublin, Edinburgh, Lisbon, London
S. Name GMT Standard Time
D. Name GMT Daylight Time
Offset  00:00:00
DST?    True

*/

Retrieving UTC Time Zone Information

When storing date and time information in an international application, UTC times are very important. One common strategy is to store all times using UTC and only converting to a local time for display purposes or reporting. This reduces the problems of comparing times in different time zones and the risk of ambiguous times that occur near the transition periods between standard and daylight saving time.

The TimeZoneInfo class includes a static property that represents a special UTC time zone. This time zone does not support daylight saving time, so has no ambiguous times, and always has an offset of zero. To access the UTC time zone information, use the static Utc property:

Console.WriteLine("ID\t{0}", TimeZoneInfo.Utc.Id);
Console.WriteLine("Name\t{0}", TimeZoneInfo.Utc.DisplayName);
Console.WriteLine("S. Name\t{0}", TimeZoneInfo.Utc.StandardName);
Console.WriteLine("D. Name\t{0}", TimeZoneInfo.Utc.DaylightName);
Console.WriteLine("Offset\t{0}", TimeZoneInfo.Utc.BaseUtcOffset);
Console.WriteLine("DST?\t{0}", TimeZoneInfo.Utc.SupportsDaylightSavingTime);

/* OUTPUT

ID      UTC
Name    UTC
S. Name UTC
D. Name UTC
Offset  00:00:00
DST?    False

*/

Retrieving a Specific Time Zone

If you wish to obtain information about a time zone that is neither the local time zone nor UTC, you can access it using the FindSystemTimeZoneById method, passing the ID of the desired time zone as the only parameter. This method is also useful if you wish to retrieve the local time zone of the user but ignore any changes they may have made to the daylight saving time setting.

TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");

Retrieving a List of Valid Time Zones

In some situations you will wish to obtain the complete list of time zones that are known by the local system. This can be achieved by calling the GetSystemTimeZones method. The method returns a ReadOnlyCollection of TimeZoneInfo objects. To output all known time zones using a foreach loop, execute the code below:

ReadOnlyCollection<TimeZoneInfo> zones = TimeZoneInfo.GetSystemTimeZones();

foreach (TimeZoneInfo zone in zones)
{
    Console.WriteLine("{0}", zone.Id);
}

Time Zone Adjustment Rules

Time zones can include rules that cause the local clock to be adjusted periodically for daylight saving time. The rules for the dates and times for such changes vary around the world and can be different for countries that are within the same geographical time zone. The TimeZoneInfo class can be used to obtain information about these time changes using instances of the nested class, "TimeZoneInfo.AdjustmentRule".

Retrieving Adjustment Rules

To obtain the list of adjustment rules for a time zone, execute the TimeZoneInfo object's GetAdjustmentRules method. This method returns an array of AdjustmentRule objects with five useful properties:

  • DateStart. This property holds a date and time value that specifies the start of the period for which the adjustment rule applies. This date is not related to the start of daylight saving time directly. It allows for multiple rules to be defined, each applying to a different period. This allows for situations where a country changes the rules for daylight saving time.
  • DateEnd. This property holds a date and time value that specifies the end of the period for which the adjustment rule applies.
  • DaylightDelta. This property returns a TimeSpan that determines the amount of time that is added during daylight saving time.
  • DaylightTransitionStart. The DaylightTransitionStart property returns a TransitionTime structure that provides rules for the transition from standard time to daylight saving time, including several properties that can be used to determine the exact date of the transition. This structure is described below.
  • DaylightTransitionEnd. This property returns a TransitionTime structure that defines the end of daylight saving time and the return to standard time.

The first three of the above properties are the simplest as they return single values. For Greenwich Mean Time (GMT), we can view the properties by executing the following sample code. This shows that the single adjustment rule is active for the entire range of dates that the .NET framework understands. The offset for this period is an increase of one hour.

TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
TimeZoneInfo.AdjustmentRule[] rules = tz.GetAdjustmentRules();
TimeZoneInfo.AdjustmentRule rule = rules[0];

Console.WriteLine(rule.DateStart);
Console.WriteLine(rule.DateEnd);
Console.WriteLine(rule.DaylightDelta);

/* OUTPUT

01/01/0001 00:00:00
31/12/9999 00:00:00
01:00:00

*/

TransitionTime Structure

The DaylightTransitionStart and DaylightTransitionEnd properties of the AdjustmentRule class define the rules for calculating the start and end of the daylight saving time period. These rules vary between countries so several properties are required. In addition, there are two manners in which a transition time can be defined. These are known as "fixed date" and "floating date". You can determine which type of rule is in use by reading the Boolean IsFixedDateRule property.

Fixed Dates

A transition with a fixed date occurs on the same date of every year. If the IsFixedDateRule property returns true, you can determine this date by reading the Day and Month properties, each of which returns an integer value. To determine the time of the transition, read the TimeOfDay property. This returns a DateTime value with the correct time set. The date portion of the TimeOfDay property should not be used.

Floating Dates

A floating date rule is required where transitions can occur on a different date from one year to the next. An example of such a rule is employed in the UK, where the transition from GMT to British Summer Time (BST) occurs at 1:00am on the last Sunday of March. To provide enough flexibility to define floating date rules, four properties are provided:

  • Month. The Month property returns an integer value that specifies the number of the month in which the transition occurs. A value of one represents January.
  • Week. The Week property returns an integer specifying the week number for the transition. A value of between one and four specifies the first, second, third or fourth week of the month. A value of five specifies that the transition occurs in the last week of the month.
  • DayOfWeek. This property returns a value from the DayOfWeek enumeration. It determines upon which day of the week the transition occurs.
  • TimeOfDay. As with the fixed date rules, the TimeOfDay property is a DateTime value with the time element representing the time of the transition.

The following shows the rules that define the transition from GMT to BST:

TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
TimeZoneInfo.AdjustmentRule[] rules = tz.GetAdjustmentRules();
TimeZoneInfo.AdjustmentRule rule = rules[0];
TimeZoneInfo.TransitionTime start = rule.DaylightTransitionStart;

Console.WriteLine("Month\t{0}", start.Month);
Console.WriteLine("Week\t{0}", start.Week);
Console.WriteLine("Day\t{0}", start.DayOfWeek);
Console.WriteLine("Time\t{0}", start.TimeOfDay.ToShortTimeString());

/* OUTPUT

Month   3
Week    5
Day     Sunday
Time    01:00

*/
Link to this Page12 October 2009
TwitterTwitter RSS Feed RSS