代码之家  ›  专栏  ›  技术社区  ›  Lonnie Best

为什么有这么多IANA时区的名字?

  •  4
  • Lonnie Best  · 技术社区  · 5 年前

    如果指定 IANA 指定时区的名称。例如:

    new Date().toLocaleString("en-US", {timeZone: "America/Chicago"});
    

    下面您可以看到IANA在每个常规时区内提供多个名称:

    America/New_York    Eastern (most areas)
    America/Detroit Eastern - MI (most areas)
    America/Kentucky/Louisville Eastern - KY (Louisville area)
    America/Kentucky/Monticello Eastern - KY (Wayne)
    America/Indiana/Indianapolis    Eastern - IN (most areas)
    America/Indiana/Vincennes   Eastern - IN (Da, Du, K, Mn)
    America/Indiana/Winamac Eastern - IN (Pulaski)
    America/Indiana/Marengo Eastern - IN (Crawford)
    America/Indiana/Petersburg  Eastern - IN (Pike)
    America/Indiana/Vevay   Eastern - IN (Switzerland)
    America/Chicago Central (most areas)
    America/Indiana/Tell_City   Central - IN (Perry)
    America/Indiana/Knox    Central - IN (Starke)
    America/Menominee   Central - MI (Wisconsin border)
    America/North_Dakota/Center Central - ND (Oliver)
    America/North_Dakota/New_Salem  Central - ND (Morton rural)
    America/North_Dakota/Beulah Central - ND (Mercer)
    America/Denver  Mountain (most areas)
    America/Boise   Mountain - ID (south); OR (east)
    America/Phoenix MST - Arizona (except Navajo)
    America/Los_Angeles Pacific
    America/Anchorage   Alaska (most areas)
    America/Juneau  Alaska - Juneau area
    America/Sitka   Alaska - Sitka area
    America/Metlakatla  Alaska - Annette Island
    America/Yakutat Alaska - Yakutat
    America/Nome    Alaska (west)
    America/Adak    Aleutian Islands
    Pacific/Honolulu    Hawaii
    

    为什么有必要这样做?

    例如,两者 美国/底特律 美洲/纽约 一般在东部时区。为什么这两个地方不共用一个 伊安娜 时区名称?

    纽约的时间和底特律的时间有什么不同吗?

    如果不是,那么为什么允许比精确的差异数更多的时区名称呢?

    1 回复  |  直到 5 年前
        1
  •  5
  •   Matt Johnson-Pint    5 年前

    我用你的例子:

    例如,美国/底特律和美国/纽约都在东部时区。为什么这两个地点不共享一个时区名?

    在TZDB中, the Zone entry for America/New_York 如下所示:

    # Zone  NAME              GMTOFF    RULES   FORMAT   [UNTIL]
    Zone    America/New_York  -4:56:02  -       LMT      1883 Nov 18 12:03:58
                              -5:00     US      E%sT     1920
                              -5:00     NYC     E%sT     1942
                              -5:00     US      E%sT     1946
                              -5:00     NYC     E%sT     1967
                              -5:00     US      E%sT
    

    同时 the Zone entry for America/Detroit 如下所示:

    # Zone  NAME              GMTOFF    RULES   FORMAT   [UNTIL]
    Zone    America/Detroit   -5:32:11  -       LMT      1905
                              -6:00     -       CST      1915 May 15  2:00
                              -5:00     -       EST      1942
                              -5:00     US      E%sT     1946
                              -5:00     Detroit E%sT     1973
                              -5:00     US      E%sT     1975
                              -5:00     -       EST      1975 Apr 27  2:00
                              -5:00     US      E%sT
    

    要完全破译这一点,还需要 Rule 条目 US , NYC Detroit (我不会在这里复制/粘贴,但您可以按照链接操作)。

    正如你所看到的,底特律与纽约有所不同,上一次是在1975年,当时底特律开始夏令时略迟于东部大部分时区(4月27日显示在这里,2月23日显示在这里 given by Rule US )

    然而,从那时起,它们是一样的。 The TZDB rules 对于自1970年以来已达成协议的区域,需要一个唯一的区域,这些区域在1973年和1975年有偏差,因此需要唯一的区域标识符。

    在javascript中可以看到这样的区别:

    var d = new Date("1975-03-01T00:00:00.000Z"); // Midnight UTC on March 1st
    d.toLocaleString("en-US", {timeZone: "America/New_York"})  //=> "2/28/1975, 8:00:00 PM"
    d.toLocaleString("en-US", {timeZone: "America/Detroit"})   //=> "2/28/1975, 7:00:00 PM"
    

    当然,如果在 你的 应用程序,你永远不会处理这么远的日期,然后你就可以使用 美洲/纽约 代表美国东部时区 美国/底特律 (还有其他一些)-但这完全是你的决定。

    您也可能有兴趣阅读 Theory 在TZDB本身中归档,这将更详细地解释时区数据库的概念和原理。