为什么 Blazor WASM 中只有几个时区可用?

Why are only a few TimeZones available in Blazor WASM?

在 Blazor WASM 中,使用 TimeZoneInfo.GetSystemTimeZones() 时似乎只有几个时区可用。为什么会这样,它们是什么控件?

@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);
    }
}

当 运行 以上时,我得到 14 个时区。当我在控制台应用程序中做类似的事情时,我得到大约。 140 个时区。我的 Win10 机器配置为 Denmark/Europe.

我通过引入一个助手 class 来解决我的问题,该助手保存我机器上可用的所有时区的序列化字符串。因此,我现在可以在 Blazor WASM 客户端中使用 TimeZoneHelper.FindTimeZone,而不是使用 TimeZoneInfo.FindSystemTimeZoneById 获取 TimeZoneInfo 对象。 它稍微扩大了有效载荷 - 但对我来说这不是问题。

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;
    }
  }
}

时区列表保存在注册表中。你在 wasm 应用程序中得到的是 IANA 时区。您可以使用 TimeZoneConverter 包将这些 TZ 转换为“conventianl”(Windows)。

可通过以下方式访问时区列表:

TZConvert.KnownRailsTimeZoneNames;

并获取特定时区(在此示例中为“太平洋标准时间”):

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