CodeGym /Courses /C# SELF /Working with Time Zones: ...

Working with Time Zones: TimeZoneInfo

C# SELF
Level 15 , Lesson 2
Available

1. Introduction

If you think time zones are just "add/subtract a few hours," you're about to feel the pain that most programmers on the planet know all too well. Time zones, daylight saving time switches, weird exceptions when you try to "convert time to another region"—all of this can lead to bugs that are hard to find and even harder to explain to users.

The worst part: there is no and never has been a "universal" understanding of time—like, two neighboring countries can treat daylight saving time differently, and sometimes decisions about switching are made in the middle of the year (yep, that's a real thing!). Example: in 2011, Samoa "jumped" over a whole day and switched sides of the international date line.

But C# and .NET give you powerful tools to at least try to deal with it. Today, let's meet our savior—the TimeZoneInfo type and its features that will help you and your app.

Why and When You Need to Work with Time Zones

  • When users/servers are in different parts of the world
  • When you store date and time in your database in UTC, but show it to the user in their local time
  • For scheduling, reminders, online events ("The webinar starts at 7:00 PM Berlin time—what about your region?")
  • When building corporate/global systems (like accounting or CRM for international business)

Overview of the TimeZoneInfo Type

TimeZoneInfo is a special class in .NET designed to represent info about a time zone: its offset from UTC, name, support for daylight saving time, and so on.

Unlike the old-school TimeZone class, which only knows about "local" and "UTC" time zones, TimeZoneInfo gives you full access to all time zones registered on the system (and even custom ones you create yourself).

2. Getting Info About Time Zones

Local and UTC Zones

Getting info about the local time zone is super easy:


// Local (i.e., where your program is running right now)
TimeZoneInfo local = TimeZoneInfo.Local;

// Always UTC
TimeZoneInfo utc = TimeZoneInfo.Utc;

Console.WriteLine(local.DisplayName); // For example: (UTC+01:00) Berlin, Vienna
Console.WriteLine(utc.DisplayName);   // (UTC) Coordinated Universal Time

All Available Time Zones

It's often necessary to show the user a list of all possible time zones (like during signup):


foreach (var tz in TimeZoneInfo.GetSystemTimeZones())
{
    Console.WriteLine($"{tz.Id} | {tz.DisplayName}");
}

This will print a list like:

  • Central European Standard Time | (UTC+01:00) Berlin, Vienna
  • Pacific Standard Time | (UTC-08:00) Pacific Time (US & Canada)
  • and so on

Visualization: Main Properties of TimeZoneInfo

Property Description
Id
System identifier for the time zone (used for searching)
DisplayName
User-friendly description (with hours and cities)
StandardName
Name for "standard" time
DaylightName
Name for daylight saving time
BaseUtcOffset
Offset from UTC (like +01:00 for Berlin)
SupportsDaylightSavingTime
True if the time zone supports daylight saving time changes

3. Converting Time Between Time Zones

This is what it's all about! You need to:

  • Convert time from one zone to another (like, the server saved it in UTC, but you show it to the user in their zone)
  • Handle daylight saving time switches correctly

General Syntax


DateTime utcNow = DateTime.UtcNow;

// For example, let's convert this time to Central European Time
TimeZoneInfo europeZone = TimeZoneInfo.FindSystemTimeZoneById("Central European Standard Time");
DateTime europeTime = TimeZoneInfo.ConvertTimeFromUtc(utcNow, europeZone);

Console.WriteLine($"UTC now: {utcNow}");       // 2024-06-20 10:30:00
Console.WriteLine($"Europe now: {europeTime}"); // 2024-06-20 11:30:00

Important: Always use UTC for internal calculations and storage, and only convert to the needed zone "on output"!

How Do You Find the Time Zone Identifier?

On Windows, time zone identifiers (Id) are specific (like "Central European Standard Time"), but on Linux/Unix—they're usually IANA/Olson identifiers ("Europe/Berlin", "America/New_York").

You can get the list of identifiers on your system via TimeZoneInfo.GetSystemTimeZones().

4. Converting Between Arbitrary Zones

Let's say you got a time in London (GMT/UTC+0) and want to convert it to Tokyo (UTC+9):


DateTime londonTime = new DateTime(2024, 6, 20, 12, 0, 0, DateTimeKind.Unspecified);

TimeZoneInfo londonZone = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
TimeZoneInfo tokyoZone  = TimeZoneInfo.FindSystemTimeZoneById("Tokyo Standard Time");

// Step one: convert the time to UTC (if it's local)
DateTime utc = TimeZoneInfo.ConvertTimeToUtc(londonTime, londonZone);

// Step two: convert UTC to Tokyo time
DateTime tokyoTime = TimeZoneInfo.ConvertTimeFromUtc(utc, tokyoZone);

Console.WriteLine($"London: {londonTime} | UTC: {utc} | Tokyo: {tokyoTime}");

Handling Daylight Saving Time Switches

TimeZoneInfo takes daylight saving time switches into account—if the zone supports them.


TimeZoneInfo eastern = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");

DateTime dateWinter = new DateTime(2024, 1, 1, 12, 0, 0, DateTimeKind.Unspecified);
DateTime dateSummer = new DateTime(2024, 7, 1, 12, 0, 0, DateTimeKind.Unspecified);

Console.WriteLine( TimeZoneInfo.ConvertTimeToUtc(dateWinter, eastern)); // UTC offset -5
Console.WriteLine( TimeZoneInfo.ConvertTimeToUtc(dateSummer, eastern)); // UTC offset -4 — daylight saving time!

Even if the US (from the example above) decides to ditch daylight saving time (and they talk about it every year!), your OS's time zone database will still get updated, and your code will keep working right.

5. Practical Tips and Common Mistakes

Exceptions and Gotchas

  • At the moment when clocks change (like 2:30 AM on the day of the daylight saving time switch), some times can be "nonexistent" or "repeated":
    For example, on the "fall back" day, 2:30 happens twice—and both times are different.
  • Don't forget: the list of time zones can change with OS updates! Example: some countries cancel/introduce daylight saving time.
2
Task
C# SELF, level 15, lesson 2
Locked
Displaying Local and UTC Time Zones
Displaying Local and UTC Time Zones
2
Task
C# SELF, level 15, lesson 2
Locked
Time Conversion Between Two Time Zones
Time Conversion Between Two Time Zones
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION