Why are only a few TimeZones available in Blazor WASM?

Viewed 596

In Blazor WASM only a few time zones seem to be available when using TimeZoneInfo.GetSystemTimeZones(). Why is that and what controls which they are?

@page "/"

<h1>Hello, world!</h1>

Welcome to your new app.

<SurveyPrompt Title="How is Blazor working for you?" />

<p>@((MarkupString)message)</p>

@code
{
    private string message = "";

    protected override void OnInitialized()
    {
        base.OnInitialized();

        List<string> timeZones = new();
        foreach (var tz in TimeZoneInfo.GetSystemTimeZones())
            timeZones.Add($"Tz DispName:{tz.DisplayName}, StdName:{tz.StandardName}, Id:{tz.Id}");

        message = string.Join("<br/>", timeZones);
    }
}

Output

I get 14 time zones when running the above. When I do something similar in a console app I get approx. 140 time zones. My Win10 machine is configured for Denmark/Europe.

2 Answers

The time zones list is saved in the registry. What you get in wasm app is IANA time zones. You may use TimeZoneConverter package to convert those TZ to "conventianl"(Windows) ones.

The time zones list is accessible through:

TZConvert.KnownRailsTimeZoneNames;

And to get a specific time zone (in this example "Pacific Standard Time"):

string tzName = TimeZoneConverter.TZConvert.WindowsToIana("Pacific Standard Time");
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById(tzName);

I resolved my issue by introducing a helper class holding the serialization strings of all time zones available on my machine. So, instead of obtaining a TimeZoneInfo object using TimeZoneInfo.FindSystemTimeZoneById I can now use TimeZoneHelper.FindTimeZone in the Blazor WASM client. It enlarges the payload a bit - but it's not an issue in my case.

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;

namespace Utils
{
  public static class TimeZoneHelper
  {
    public static ReadOnlyDictionary<string, string> Data { get; } = new(new Dictionary<string, string>
    {
      { "Dateline Standard Time", "Dateline Standard Time;-720;(UTC-12:00) International Date Line West;Dateline Standard Time;Dateline Daylight Time;;" },
      { "UTC-11", "UTC-11;-660;(UTC-11:00) Coordinated Universal Time-11;UTC-11;UTC-11;;" },
      { "Hawaiian Standard Time", "Hawaiian Standard Time;-600;(UTC-10:00) Hawaii;Hawaiian Standard Time;Hawaiian Daylight Time;;" },
      { "Alaskan Standard Time", "Alaskan Standard Time;-540;(UTC-09:00) Alaska;Alaskan Standard Time;Alaskan Daylight Time;[01:01:0001;12:31:2006;60;[0;02:00:00;4;1;0;];[0;02:00:00;10;5;0;];][01:01:2007;12:31:9999;60;[0;02:00:00;3;2;0;];[0;02:00:00;11;1;0;];];" },
      { "UTC-09", "UTC-09;-540;(UTC-09:00) Coordinated Universal Time-09;UTC-09;UTC-09;;" },
      { "Pacific Standard Time (Mexico)", "Pacific Standard Time (Mexico);-480;(UTC-08:00) Baja California;Pacific Standard Time (Mexico);Pacific Daylight Time (Mexico);[01:01:0001;12:31:2009;60;[0;02:00:00;4;1;0;];[0;02:00:00;10;5;0;];][01:01:2010;12:31:9999;60;[0;02:00:00;3;2;0;];[0;02:00:00;11;1;0;];];" },
      { "Pacific Standard Time", "Pacific Standard Time;-480;(UTC-08:00) Pacific Time (US & Canada);Pacific Standard Time;Pacific Daylight Time;[01:01:0001;12:31:2006;60;[0;02:00:00;4;1;0;];[0;02:00:00;10;5;0;];][01:01:2007;12:31:9999;60;[0;02:00:00;3;2;0;];[0;02:00:00;11;1;0;];];" },
      { "Central America Standard Time", "Central America Standard Time;-360;(UTC-06:00) Central America;Central America Standard Time;Central America Daylight Time;;" },
      { "Central Standard Time", "Central Standard Time;-360;(UTC-06:00) Central Time (US & Canada);Central Standard Time;Central Daylight Time;[01:01:0001;12:31:2006;60;[0;02:00:00;4;1;0;];[0;02:00:00;10;5;0;];][01:01:2007;12:31:9999;60;[0;02:00:00;3;2;0;];[0;02:00:00;11;1;0;];];" },

      // Shortened. Generate and paste full content using:
      //   foreach (var tz in TimeZoneInfo.GetSystemTimeZones())
      //     Console.WriteLine($"{{ \"{tz.Id}\", \"{tz.ToSerializedString()}\" }},");

    });

    public static TimeZoneInfo FindTimeZone(string id)
    {
      if (id == null)
        throw new ArgumentNullException(nameof(id));
     
      if (!Data.TryGetValue(id, out string data))
        throw new TimeZoneNotFoundException("Unknown time zone id: " + id);

      var tz = TimeZoneInfo.FromSerializedString(data);
      return tz;
    }
  }
}
Related