TimeZoneInfo with current UTC offset in C#

By FoxLearn 3/6/2025 7:26:58 AM   13
TimeZoneInfo provides the base UTC offset, which can lead to confusion since the offset may vary depending on the date due to daylight saving time.

For example, How to use DateTimeOffset and TimeZoneInfo to display the current offset:

DateTimeOffset.Now -> “6/27/2025 4:40:00 PM +02:00“
TimeZoneInfo.Local.DisplayName -> “(UTC+01:00) Central European Standard Time”

You can retrieve a date's UTC offset using DateTimeOffset and combine it with TimeZoneInfo.DisplayName. This functionality is implemented in the following extension method:

public static class TimeZoneInfoExtensions
{
    public static string GetDisplayNameWithCurrentOffset(this TimeZoneInfo timezone, DateTimeOffset date)
    {
        if (!timezone.SupportsDaylightSavingTime)
            return timezone.DisplayName;

        // Example: Removes (UTC+01:00)
        var displayNameWithoutOffset = timezone.DisplayName.Remove(0, 11);

        var currentOffset = TimeZoneInfo.ConvertTime(date, timezone).Offset;
        var currentOffsetHHMM = currentOffset.ToString("hh\\:mm");

        if (currentOffset < TimeSpan.Zero)
        {
            return $"(UTC-{currentOffsetHHMM}){displayNameWithoutOffset}";
        }
        else
        {
            return $"(UTC+{currentOffsetHHMM}){displayNameWithoutOffset}";
        }
    }
}

Here’s an example of using this extension method to get the local time zone along with the current UTC offset from today’s date (DateTimeOffset.Now):

var defaultDisplayName = TimeZoneInfo.Local.DisplayName;
Console.WriteLine($"Display Name (base offset): {defaultDisplayName}");

var localNow = DateTimeOffset.Now;
var displayNameWithCurrentOffset = TimeZoneInfo.Local.GetDisplayNameWithCurrentOffset(localNow);
Console.WriteLine($"Display Name (current offset): {displayNameWithCurrentOffset}");

Output:

Display Name (base offset): (UTC+01:00) Central European Standard Time
Display Name (current offset): (UTC+02:00) Central European Standard Time

Get All System Time Zones and Display Them with Current UTC Offsets

In this example, we retrieve all system time zones along with their current UTC offsets:

var localNow = DateTimeOffset.Now;

foreach (var timeZone in TimeZoneInfo.GetSystemTimeZones())
{
    var defaultDisplayName = timeZone.DisplayName;
    Console.WriteLine($"Display Name (base offset): {defaultDisplayName}");

    var displayNameWithCurrentOffset = timeZone.GetDisplayNameWithCurrentOffset(localNow);
    Console.WriteLine($"Display Name (current offset): {displayNameWithCurrentOffset}");
}

Output:

Display Name (base offset): (UTC+01:00) Central European Standard Time
Display Name (current offset): (UTC+02:00) Central European Standard Time
...
Display Name (base offset): (UTC+08:00) Perth
Display Name (current offset): (UTC+08:00) Perth
...

Get a Time Zone by ID and Display It with the Current UTC Offset

Here’s how to look up a time zone by its ID and retrieve its current UTC offset:

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

var defaultDisplayName = centralEuropeanTimeZone.DisplayName;
Console.WriteLine($"Display Name (base offset): {defaultDisplayName}");

var displayNameWithCurrentOffset = centralEuropeanTimeZone.GetDisplayNameWithCurrentOffset(DateTimeOffset.Now);
Console.WriteLine($"Display Name (current offset): {displayNameWithCurrentOffset}");

Output:

Display Name (base offset): (UTC+01:00) Central European Standard Time
Display Name (current offset): (UTC+02:00) Central European Standard Time