【问题标题】:Long form name of timezone in NodaTimeNodaTime 中时区的长格式名称
【发布时间】:2014-08-01 17:55:20
【问题描述】:

在 NodaTime 中,如何在给定 tz 时区 id 的情况下找到时区的长格式名称?

例如,如果我提供“America/Los_Angeles”,我应该返回“太平洋标准时间”。

【问题讨论】:

  • 不要认为它是重复的。我不想在两者之间转换。我只想要友好/长格式名称
  • 只是发牢骚:“America/Los_Angeles”不应该返回“太平洋时间”(PT)而不是“太平洋标准时间”(PST)吗?洛杉矶仅在冬季使用 PST,在夏季使用“太平洋夏令时间”(PDT)。 PT 等于冬季的 PST 和夏季的 PDT,这是一个更好的选择,或者像“太平洋标准|夏令时”这样的东西会更准确。

标签: c# datetime nodatime


【解决方案1】:

生成“长格式”时区名称所需的信息不在野田时间,但可以CLDR 中找到。

我最近整理了一个名为“时区名称”的库,其中嵌入了 CLDR 时区名称。您可以将它们与野田时区使用的 IANA (TZDB) 标识符一起使用。

只需传递时区和语言,它就会提供适当的通用名称、标准名称和夏令时名称。您可以使用 Noda Time 来决定适合显示的表格。

var names = TimeZoneNames.GetNamesForTimeZone("America/Los_Angeles", "en-US");

Assert.Equal("Pacific Time", names.Generic);
Assert.Equal("Pacific Standard Time", names.Standard);
Assert.Equal("Pacific Daylight Time", names.Daylight);

对于语言,您可以传递两位数字代码,例如 "en",也可以传递完全区域化的版本,例如 "en-US"。这与 CultureInfo 名称一致,因此您可以根据需要传递 CultureInfo.CurrentUICulture.Name

【讨论】:

  • CLDR 似乎有一些错误。它将“MST7MDT”称为“山地标准时间”,但实际名称只是“山地时间”。 “MST”,一个不同的时区,被恰当地称为“山地标准时间”。不同之处并非纯粹是学术上的:在美国夏季,亚利桑那州采用“山地标准时间”,而新墨西哥州采用常规的“山地时间”,提前一个小时,因为“山地时间”在夏天。
  • @barrycarter - 是的,这就是输出中names.Genericnames.Standard 之间存在差异的原因。我检查了MST7MDT 就像你描述的那样工作。您可以看到in the cldr 它位于America_Mountain 元区域中。无论如何,如果您对 CLDR 有进一步的疑虑,请将它们发送给 CLDR。如果您对我的图书馆有疑问,log them at the project site。谢谢。
  • 谢谢,马特,我已经这样做了。我实际上指的是“windowsZones.xml”文件,这是唯一一个似乎有完整时区名称的文件?
  • 不,名称在 /common/main 中特定于语言环境的文件中,例如 /common/main/en.xml。不要使用 Windows ID 作为名称。
【解决方案2】:

TZDB 本身不包含对时区的描述:ID 为 America/Los_Angeles 的时区只包含名称为“PDT”和“PST”的转换。所以从这个角度来看,数据根本就不存在。

也就是说,您可以获取映射到给定 TZDB 区域(最初来自 the CLDR windowsZones.xml data)的 Windows 时区 ID,并且 Windows 通常会为其区域使用“太平洋标准时间”之类的名称ID。

例如

var source = TzdbDateTimeZoneSource.Default;
var windowsIds = (from item in source.WindowsMapping.PrimaryMapping
    where item.Value == "America/Los_Angeles"
    select item.Key).ToList();

但是,这种方法有一些注意事项:

  • 如上所示,可能有任意数量的 Windows 区域 ID 映射到给定的 TZDB 区域。在当前数据中,这始终是零或一(Europe/Vienna 是没有 Windows 区域 ID 使用的 TZDB 区域的示例),但理论上没有理由找不到两个或更多 Windows 区域 ID 映射到同一个 TZDB 区域。
  • 一些 Windows 区域 ID 不是特别好:例如,Europe/London 映射自一个名为“GMT 标准时间”的 Windows 区域,这不是向用户显示的好字符串。

但是,对于您正在做的事情,这可能是可以接受的。

【讨论】:

    【解决方案3】:

    简答:https://github.com/barrycarter/bcapps/blob/master/ASTRO/tz2name.txt

    长答案:正如其他人所指出的,您可以使用 CLDR 的 common/supplemental/metaZones.xml 文件将时区映射到区域。例如:

                        <timezone type="America/Barbados">
                                <usesMetazone mzone="Atlantic"/>
                        </timezone>
    

    将时区“美国/巴巴多斯”映射到“大西洋”地区。

    然后您可以使用common/main/en.xml 将区域转换为时区名称。例如:

                        <metazone type="Atlantic">
                                <long>
                                        <generic>Atlantic Time</generic>
                                        <standard>Atlantic Standard Time</standard>
                                        <daylight>Atlantic Daylight Time</daylight>
                                </long>
                                <short>
                                        <generic>AT</generic>
                                        <standard>AST</standard>
                                        <daylight>ADT</daylight>
                                </short>
                        </metazone>
    

    告诉我们在“大西洋”地区使用的时区名称(长格式和短格式)。

    这几乎是其他答案的重复,但直接引用了相关文件。

    【讨论】:

      猜你喜欢
      • 2018-09-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多