如何解决在 Edge 和 chrome 中获取不同时区名称的问题

How to fix the issue of getting different time zone name in Edge and chrome

我需要使用下面的代码使用 Jquery 获取时区名称。

当我在系统设置中 select UTC+5.30(chennai,kolkatta,mumbai,newdelhi) 时区时,我在边缘和 chrome 浏览器中得到 "India Standard Time"

但是当我在设置中更改为 (UTC+5.30) Sri Jayawardenepura 时,Chrome 显示 "India Standard Time",Edge 显示 "Srilanka Standard Time",这是正确的。有谁能找出差异的原因并给我一个解决方案吗?

我用过

(new Date).toString().split('(')[1].slice(0, -1);

var timeZone = (new Date).toString().split('(')[1].slice(0, -1);

时区令人困惑。

您需要的是时区名称。

时区名称的格式通常为 'Asia/city_name'

连同日期和 utc 偏移量,这就是您需要进行时间转换的内容(并且在转换为本地时间之前始终使用 UTC 进行这些操作)

如果您正在查看的地方遵守夏令时,您从 chrome 或 edge 获得的时区偏移名称可能会在一年中发生变化,因此使用它是不正确的。

对于 time/timezone 查找,使用 momentjs 时区

https://momentjs.com/timezone/

您使用的方法是从 Date.prototype.toString 的输出中提取括号中的值。该值由 20.3.4.41.3 of the current ECMAScript spec 部分 TimeZoneString 下的 tzName 定义(在我撰写本文时为 10.0)。

它说(强调我的):

Let tzName be an implementation-defined string that is either the empty string or the string-concatenation of the code unit 0x0020 (SPACE), the code unit 0x0028 (LEFT PARENTHESIS), an implementation-dependent timezone name, and the code unit 0x0029 (RIGHT PARENTHESIS).

因此,您不应期望它们在任何特定浏览器上具有任何特定值,也不应期望它们匹配。

也就是说,我可以解释您注意到的行为。

  • Edge 从与您选择的时区关联的本地化显示名称中获取其 tzName 值。这些在 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\Sri Lanka Standard Time 的注册表中,在 StdDlt 字段中,以您使用的日期为准。

  • Chrome 的 tzName 值来自 Unicode CLDR internationalization data (via ICU):

    • 它首先使用windowsZones.xml file to map the Sri Lanka Standard Time Windows time zone ID to the Asia/Colombo IANA时区ID。

      <!-- (UTC+05:30) Sri Jayawardenepura -->
      <mapZone other="Sri Lanka Standard Time" territory="001" type="Asia/Colombo"/>
      <mapZone other="Sri Lanka Standard Time" territory="LK" type="Asia/Colombo"/>
      
    • 然后使用 metaZones.xml 文件将 Asia/Colombo 分配给 India CLDR MetaZone。

      <timezone type="Asia/Colombo">
          <usesMetazone to="1996-05-24 18:30" mzone="India"/>
          <usesMetazone to="2006-04-14 18:30" from="1996-05-24 18:30" mzone="Lanka"/>
          <usesMetazone from="2006-04-14 18:30" mzone="India"/>
      </timezone>
      
    • 然后使用活动语言文件,例如 en.xml 来确定要用于 India MetaZone 的显示名称。

      <metazone type="India">
          <long>
              <standard>India Standard Time</standard>
          </long>
      </metazone>
      

      这就变成了tzNamereturn括号里的Date.prototype.toString.

请注意,虽然 Edge 和 Chrome 对 Date.prototype.toString 输出使用不同的来源,但 Edge 也使用 CLDR 来实现 ECMAScript Internationalization API.这可以通过以下方式看到:

new Date().toLocaleString(undefined, {timeZoneName: 'long'})

将您的时区设置为斯里兰卡,Edge 和 Chrome 都将 return:

"8/16/2019, 10:41:31 PM India Standard Time"

其他几点:

  • 请注意,显示值也会因操作系统的语言设置以及对提供的日期有效的时区部分而改变。例如,在美国太平洋时区,在英语中,您将看到 "Pacific Standard Time""Pacific Daylight Time"。您将在法语、日语等语言中看到不同的值。因此,它仅用于向最终用户显示。它不应被分开解析并视为标识符。

  • 要获取实际的 IANA tzdb 标识符,例如 Asia/ColomboAsia/KolkataAmerica/Los_Angeles,请参阅