How to use TimeZoneInfo in C#

By FoxLearn 3/6/2025 9:17:04 AM   25
Time zones can be tricky due to their varying rules and changes, so leveraging a library is a smart approach. In .NET, one such option is the built-in TimeZoneInfo class.

For example, Using TimeZoneInfo to obtain the local system's time zone:

var localTimeZone = TimeZoneInfo.Local;

Console.WriteLine($"Time zone display name: {localTimeZone.DisplayName}"); //same as .ToString()
Console.WriteLine($"Time zone id (Windows): {localTimeZone.Id}");

Output:

Time zone display name: (UTC-06:00) Central Time (US & Canada)
Time zone id: Central Standard Time

Note: The display name reflects the base UTC offset (-06:00) and may not accurately represent the current UTC offset if daylight saving time is in effect, which can be misleading.

Warning: IANA ID support was introduced in .NET 6. If you're using an earlier version, attempting to use an IANA ID will result in a TimeZoneNotFoundException. Stick to Windows time zone IDs if you're using a version prior to .NET 6.

How to use TimeZoneInfo in C#?

Get a Time Zone by ID

You can retrieve a time zone using either its Windows time zone ID (e.g., "Central Standard Time") or its IANA ID (e.g., "America/Chicago").

For example, How to get a time zone using its Windows time zone ID:

var centralTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Central Standard Time");

Console.WriteLine($"Id: {centralTimeZone.Id}");
Console.WriteLine($"Display name: {centralTimeZone.DisplayName}");
Console.WriteLine($"Has IANA id? {centralTimeZone.HasIanaId}");

Output:

Id: Central Standard Time
Display name: (UTC-06:00) Central Time (US & Canada)
Has IANA id? False

For example, How to get a time zone using its IANA ID:

var chicagoTimeZone = TimeZoneInfo.FindSystemTimeZoneById("America/Chicago");

Console.WriteLine($"Id: {chicagoTimeZone.Id}");
Console.WriteLine($"Display name: {chicagoTimeZone.DisplayName}");
Console.WriteLine($"Has IANA id? {chicagoTimeZone.HasIanaId}");

Warning: This will only work in .NET 6 and above. Using earlier versions will raise a TimeZoneNotFoundException.

Output:

Id: America/Chicago
Display name: (UTC-06:00) Central Time (US & Canada)
Has IANA id? True

Note: The HasIanaId property indicates whether the IANA ID can be used to look up the time zone with TimeZoneInfo.FindSystemTimeZoneById().

Convert Between Time Zones

Here’s an example of converting a DateTimeOffset object from one time zone to another:

var eventTimeLocal = DateTimeOffset.Now;
var eventTimeNY = TimeZoneInfo.ConvertTimeBySystemTimeZoneId(eventTimeLocal, "Eastern Standard Time");

Console.WriteLine($"Event local time: {eventTimeLocal}");
Console.WriteLine($"Event NY time: {eventTimeNY}");

Output:

Event local time: 2/15/2025 10:30:00 AM -05:00
Event NY time: 2/15/2025 11:30:00 AM -05:00

If you already have the TimeZoneInfo object, you can use TimeZoneInfo.ConvertTime() like this:

var usPacificTimeZone = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
var pacificTimeNow = TimeZoneInfo.ConvertTime(DateTimeOffset.Now, usPacificTimeZone);

Convert from Windows Time Zone ID to IANA ID

In .NET 6, you can convert between Windows time zone IDs and IANA IDs easily.

For example, How to convert a Windows time zone ID to an IANA ID:

var windowsTimeZoneID = TimeZoneInfo.Local.Id;

if (TimeZoneInfo.TryConvertWindowsIdToIanaId(windowsTimeZoneID, out string? ianaId))
{
    Console.WriteLine($"Windows time zone id ({windowsTimeZoneID}) = IANA ID ({ianaId})");
}

Output:

Windows time zone id (Central Standard Time) = IANA ID (America/Chicago)

And conversely, from an IANA ID to a Windows time zone ID:

var ianaIdFromClient = "America/Chicago";

if (TimeZoneInfo.TryConvertIanaIdToWindowsId(ianaIdFromClient, out string? windowsId))
{
    Console.WriteLine($"Windows time zone id ({windowsId}) = IANA ID ({ianaIdFromClient})");
}

Output:

Windows time zone id (Central Standard Time) = IANA ID (America/Chicago)

Get a List of All System Time Zones

To retrieve all system time zones (as TimeZoneInfo objects), use TimeZoneInfo.GetSystemTimeZones():

foreach (var timezone in TimeZoneInfo.GetSystemTimeZones())
{
    Console.WriteLine(timezone.Id);
}

Output:

...
Central Standard Time
Mountain Standard Time
Eastern Standard Time
...

Get IANA IDs for All System Time Zones

If you want to generate a list of system time zones along with their IANA IDs, combine GetSystemTimeZones() and TryConvertWindowsIdToIanaId():

var timeZoneList = TimeZoneInfo.GetSystemTimeZones().Select(tz =>
{
    TimeZoneInfo.TryConvertWindowsIdToIanaId(tz.Id, out string? IanaId);
    return new
    {
        IanaId,
        tz.DisplayName
    };
});

foreach (var timeZone in timeZoneList)
{
    Console.WriteLine($"{timeZone.IanaId} - {timeZone.DisplayName}");
}

Output:

...
America/Chicago - (UTC-06:00) Central Time (US & Canada)
America/New_York - (UTC-05:00) Eastern Time (US & Canada)
America/Los_Angeles - (UTC-08:00) Pacific Time (US & Canada)
...

Remember that Windows time zone IDs can correspond to multiple IANA IDs, but the converter methods will only return one.