如何获取 UTC TimeZone DisplayName .NET 4.0?

How to get UTC TimeZone DisplayName .NET 4.0?

我用时区 DisplayName 设置了一个 winforms 组合框:

        var zoneList = TimeZoneInfo
            .GetSystemTimeZones()
            .Where(z => z.BaseUtcOffset.Minutes == 0)
            .Select(z => z.DisplayName);

它显示了这样一个列表:

    ... 
    (UTC-01:00) Azores 
    (UTC-01:00) Cabo Verde Is. 
    (UTC) Casablanca 
    (UTC) Co-ordinated Universal Time 
    (UTC) Dublin, Edinburgh, Lisbon, London 
    (UTC) Monrovia, Reykjavik 
    (UTC+01:00) Amsterdam, Berlin, Bern, Rome, Stockholm, Vienna 
    ...

我想将默认项目发送到 (UTC) Co-ordinated Universal Time。然而,TimeZoneInfo.Utc.DisplayNamereturnsUTC。这是不寻常的,因为上面的枚举显示不同的 DisplayName。

TimeZoneInfo.FindSystemTimeZoneById("UTC") 也 returns "UTC"。 TimeZoneInfo.FindSystemTimeZoneById("(UTC) Co-ordinated Universal Time")TimeZoneInfo.FindSystemTimeZoneById("Co-ordinated Universal Time") 不起作用。

如何获取枚举中显示对应的本地化字符串(UTC) Co-ordinated Universal Time?

我能想到的唯一解决方案是存储字符串 "(UTC) Co-ordinated Universal Time",但我担心上面的列表可能会在不同的本地化中发生变化。

嗯,我通过打印时区的 Id 找到了答案。

所需字符串打印为:

      TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time"); // Wrong

编辑: 正如 Matt Johnson 指出的那样,上面的代码显示了伦敦时区。

这是另一个尝试:

      TimeZoneInfo.GetSystemTimeZones().First(t=>t.Id=="UTC").DisplayName

几件事:

  • DisplayName不是ID。只有 Id 属性 返回的值才适合与 FindSystemTimeZoneById 方法一起使用。

  • 对于您的下拉列表,您应该显示 DisplayName,但您应该 storeId.

  • DisplayNameStandardNameDaylightName 属性由操作系统 本地化 ,而不是全球化.NET Framework 的功能。

  • ID 将始终为英文。他们永远不会因本地化而改变。

  • 您应该永远不要向最终用户显示 ID 或以任何特定方式解释它们。使用了许多不同的相互冲突的约定,有些只是编造的。有关示例,请参阅 the timezone tag wiki 中有关 Windows 时区的部分。

  • "Coordinated" 是单个非连字符单词。这些在 Windows 中是正确的,所以我想你一定是自己添加了连字符。

  • 认识到显示名称中显示的偏移量只是基本偏移量。它们不指示时区是否针对夏令时进行调整。当夏令时生效时,此列表中的偏移量也不会更改。

  • 你是对的TimeZoneInfo.Utc.DisplayName == "UTC"TimeZoneInfo.FindSystemTimeZoneById("UTC").DisplayName也是如此。但是,TimeZoneInfo.GetSystemTimeZones() 返回的 UTC 条目具有显示名称的完整形式:"(UTC) Coordinated Universal Time"。因此,如果您通过枚举 TimeZoneInfo.GetSystemTimeZones() 的结果来显示下拉列表,那么您可以按原样使用结果。

    但是如果你想直接得到那个显示名称,你要么必须这样做:

    string s = TimeZoneInfo.GetSystemTimeZones().First(x => x.Id == "UTC").DisplayName;
    

    或者,这个:

    string key = @"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\UTC";
    string s = Registry.GetValue(key, "Display", null) as string;
    

    再次提醒,时区显示名称的所有本地化都是由操作系统完成的。因此,这种方法适用于 Windows 桌面应用程序,但对 Web 应用程序没有多大意义。此外,如果您的应用程序在内部支持多种语言,您将无法依赖 .NET 全球化来获得任何时区显示名称。在这种情况下,您将需要提供自己的显示名称来源,可能在 .resx 文件中,或者您可以考虑使用我的 TimeZoneNames 库。