如何在 NodaTime 中获取时区列表

How to get list of timezones in NodaTime

如何从 NodaTime 获取 "time zones" 的列表,以便我可以制作如下所示的 UI 供我的用户选择?

我想显示 UTC 偏移量,然后显示适当的 cities/countries/locations。它不需要完全像下面这样,但你知道,有些接近。

DateTimeZone 没有名称 属性,ToString()ing 生成重复项(来自 IDateTimeZoneProviderIds 列表)。

我看到您可以使用 TzdbDateTimeZoneSource.Default.ZoneLocations 从 ~countries 到 zones ,但这也不是我正在寻找的。我可以看到如何将这两个数据源拼凑在一起,但这感觉像是一个已解决的问题,我不应该重新发明。

野田时间目前不提供面向用户的时区字符串,不。

这方面的最佳数据来源是 CLDR. We have a long-standing issue,但不幸的是,它从根本上来说很棘手。在某些时候我想回到它,但我还没有找到时间:(

您可以使用 Onism.Cldr 项目访问 CLDR 数据。不过,您需要了解 CLDR 数据在两个方面的工作原理:

  • metazones等时区数据结构
  • 允许您以用户选择的语言获取特定字符串资源的文本数据结构

抱歉,目前的答案实际上只是 "No, there's nothing out of the box" - 但事实就是这样 :(

您可以考虑使用 GeoTimeZone Nuget 包来按位置获取 IANA 时区 ID,例如纬度和经度

// using coordinates for a place in London use GeoTimeZone Library
string tz = GeoTimeZone.TimeZoneLookup.GetTimeZone(50.4372, -3.5559).Result; // Europe/London

DateTimeZone dateTimeZone = DateTimeZoneProviders.Tzdb.GetZoneOrNull(tz);

//You can get the UTC timeoffset at any instant possibly like this
Offset offset = dateTimeZone
            .GetUtcOffset(SystemClock.Instance.GetCurrentInstant());

Console.WriteLine(offset); //+01

您可以获得显示名称列表及其相应的 IANA 时区 ID,适用于按照您描述的方式构建下拉列表,使用我的 TimeZoneNames 库。生成的 ID 与 NodaTime 的 TZDB 提供程序兼容。

// You can either hardcode the language (ex: "en-US"), or get it from .NET globalization:
var languageCode = CultureInfo.CurrentUICulture.Name;

// Then get the names, as a list of key/value pairs
var list = TZNames.GetDisplayNames(languageCode, useIanaZoneIds: true);

// Use them as you wish.  For example:
foreach (var name in list)
{
    Console.WriteLine($"{name.Key} = \"{name.Value}\"");
}

输出(截断):

Etc/GMT+12 = "(UTC-12:00) International Date Line West"
Etc/GMT+11 = "(UTC-11:00) Coordinated Universal Time-11"
America/Adak = "(UTC-10:00) Aleutian Islands"
Pacific/Honolulu = "(UTC-10:00) Hawaii"
Pacific/Marquesas = "(UTC-09:30) Marquesas Islands"
America/Anchorage = "(UTC-09:00) Alaska"
Etc/GMT+9 = "(UTC-09:00) Coordinated Universal Time-09"
America/Tijuana = "(UTC-08:00) Baja California"
Etc/GMT+8 = "(UTC-08:00) Coordinated Universal Time-08"
America/Los_Angeles = "(UTC-08:00) Pacific Time (US & Canada)"
America/Phoenix = "(UTC-07:00) Arizona"
America/Chihuahua = "(UTC-07:00) Chihuahua, La Paz, Mazatlan"
America/Denver = "(UTC-07:00) Mountain Time (US & Canada)"
America/Guatemala = "(UTC-06:00) Central America"
America/Chicago = "(UTC-06:00) Central Time (US & Canada)"
Pacific/Easter = "(UTC-06:00) Easter Island"
...

显示名称来自 Windows 语言包。 ID 通过 CLDR 从 Windows 转换为 IANA。如果您想要 Windows ID,则可以将 useIanaZoneIds 设置为 false(或省略它)。

另请参阅 TimeZoneNames 文档中的 Methods for listing time zones and the Acknowledgements