Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate list of Windows-like friendly time zone names on Linux .NET Core

We have a .NET 4.7 MVC 5 web app, running under Windows, that allows users to select their time zone using the standard Windows display names like (UTC+00:00) Dublin, Edinburgh, Lisbon, London:

Windows time zone display names

We would like to provide the same list of time zone options through a new API built with .NET Core 2.0, which will run in a Linux docker container. Is this possible?

I have found Matt Johnson's excellent TimeZoneConverter package, which does a great job at converting between Windows's GMT Standard Time and IANA's Europe/London. However, I can't seem to get the Windows display name from anywhere.

Here's some example code to list some time zone information:

var timeZoneIds = TimeZoneConverter.TZConvert.KnownWindowsTimeZoneIds.ToList();

foreach (var timeZoneId in timeZoneIds.Take(4))
{
    if (TimeZoneConverter.TZConvert.TryGetTimeZoneInfo(timeZoneId, out var timeZoneInfo))
    {
        Console.WriteLine($"Windows Id:   {timeZoneId}");
        Console.WriteLine($".NET Id:      {timeZoneInfo.Id}");
        Console.WriteLine($"Display name: {timeZoneInfo.DisplayName}");
        Console.WriteLine("----");
    }
}

When run on my Windows development machine, it gives this output:

Windows Id:   AUS Central Standard Time
.NET Id:      AUS Central Standard Time
Display name: (UTC+09:30) Darwin
----
Windows Id:   AUS Eastern Standard Time
.NET Id:      AUS Eastern Standard Time
Display name: (UTC+10:00) Canberra, Melbourne, Sydney
----
Windows Id:   Afghanistan Standard Time
.NET Id:      Afghanistan Standard Time
Display name: (UTC+04:30) Kabul
----
Windows Id:   Alaskan Standard Time
.NET Id:      Alaskan Standard Time
Display name: (UTC-09:00) Alaska
----

When run inside a Linux docker container, we get this:

Windows Id:   AUS Central Standard Time
.NET Id:      Australia/Darwin
Display name: GMT+09:30
----
Windows Id:   AUS Eastern Standard Time
.NET Id:      Australia/Sydney
Display name: GMT+10:00
----
Windows Id:   Afghanistan Standard Time
.NET Id:      Asia/Kabul
Display name: GMT+04:30
----
Windows Id:   Alaskan Standard Time
.NET Id:      America/Anchorage
Display name: GMT-09:00
----

Is there any way to get (say) (UTC+10:00) Canberra, Melbourne, Sydney when running inside the Linux docker container?

Possible hacks or workarounds I've thought of so far:

  • Hard-code the list of Windows display names in the API source
  • Generate a "good enough" display name from the info that we do have, like (GMT+10:00) AUS Eastern Standard Time
  • See if Matt Johnson's TimeZoneNames package can used to generate a friendly list
like image 421
Paul Stephenson Avatar asked Nov 14 '18 12:11

Paul Stephenson


1 Answers

This is now possible with TimeZoneNames version 4.0.0.

string languageCode = CultureInfo.CurrentCulture.IetfLanguageTag; // ex: "en-US"
var displayNames = TZNames.GetDisplayNames(languageCode);

The result is a dictionary where the key is the Windows ID of the time zone, and the value is the localized display name.

If you want to return IANA time zone names as keys instead, then pass true as an optional second parameter:

var displayNames = TZNames.GetDisplayNames(languageCode, true);
like image 196
Matt Johnson-Pint Avatar answered Oct 07 '22 23:10

Matt Johnson-Pint