【问题标题】:Chrome timeZone option to Date.toLocaleString()Date.toLocaleString() 的 Chrome 时区选项
【发布时间】:2013-07-02 22:04:06
【问题描述】:

我最近发现 JavaScript 有一个新的扩展。这为toLocaleStringtoLocaleDateStringtoLocaleTimeString 函数中的Date 对象添加了几个功能。 Reference here.

我对支持IANA/Olson time zonestimeZone 选项特别感兴趣,例如America/New_YorkEurope/London目前仅在 Google Chrome 中支持

之前的建议是,要在 JavaScript 中使用除 UTC 或您自己的本地时区以外的任何其他时区,必须use a library。但现在,这似乎开始直接整合到浏览器中。所以现在你可以这样做了:

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

// output: "7/4/2013 5:15:45 PM"

或者:

new Date().toLocaleString("en-NZ", {timeZone: "Pacific/Chatham",
                                    timeZoneName: "long"})

// output:  "7/5/2013 9:59:52 AM GMT+12:45"

或者:

new Date().toLocaleString("en-GB", {timeZone: "Europe/London",
                                    timeZoneName: "short"})

// output:  "4/7/2013 22:18:57 United Kingdom Time"
// (strange time zone name, but ok)

非常很酷,但我有几个问题:

  • 这是新标准的一部分吗?也许埋在 ECMAScript 6 的某个地方?还是它只是 Chrome 的自定义功能?
  • 为什么只有谷歌浏览器?它在其他任何地方都支持吗?是否有计划在其他任何地方支持它?
  • 我检查了使用 Chrome 的 JavaScript 运行时的 node.js,但它在那里不起作用。为什么不呢?
  • 是否可以通过我列出的函数以外的任何其他方式访问时区数据?如果仅在格式化字符串时可用,那么根据结果进行任何计算可能会很困难。
  • 这专注于输出,但我将如何将其用于输入?有没有办法将构造函数中的时区传递给Date 对象?我尝试了以下方法:

    // parsing it with a date and time
    new Date("2013-01-01 12:34:56 America/New_York")
    
    // passing it as a named option
    new Date(2013,0,1,12,34,56,{timeZone:"America/New_York"})
    

    都没有用。我在规格中找不到任何东西,所以我认为这不存在(目前),但如果我错了,请告诉我。

  • this post 中描述的问题是由 ECMAScript 5 规范中的缺陷造成的,即使 TZD​​B 中有正确的数据,它仍然会影响输出。新旧实现如何共存?人们会认为这将是所有旧方式或所有新方式。例如,我的计算机时区设置为美国东部时间:

    new Date(2004,10,7,0,0).toLocaleString("en-US",{timeZone:"America/New_York"})
    

    返回"11/6/2004 11:00:00 PM"。它应该返回午夜,因为我从午夜开始并且我的本地时区与输出时区匹配。但由于 ES5 问题,它将提供的输入日期置于错误的 UTC 点。

  • 我可以期待随着 IANA 发布对 TZDB 的更新,Google 会推送包含这些更改的 Chrome 更新吗?

【问题讨论】:

    标签: javascript google-chrome internationalization timezone ecmascript-intl


    【解决方案1】:

    更新

    关于 API here 的文章相当广泛


    这是新标准的一部分吗?也许埋在 ECMAScript 的某个地方 6?还是只是 Chrome 的自定义功能?

    是的,这些是ECMAScript Internationalization API 的一部分。它与 ECMAScript 分开实现,但实现 ECMAScript 国际化 API 的要求是首先正确实现 ECMAScript 5.1

    为什么只有谷歌浏览器?它在其他任何地方都支持吗?有没有计划 在其他任何地方都支持它?

    近年来,谷歌浏览器大多率先实施新功能。 Mozilla 比较保守,比如还在讨论是否实现a 元素的download 属性。它现在也可以在IE11 BetaOpera 中使用。它将在Firefox 25 中提供。

    我检查了 node.js,它使用 Chrome 的 JavaScript 运行时,但它 在那里不起作用。为什么不呢?

    node.js 只是使用相同的引擎,即来自 Google Chrome 浏览器的 a separate project。该引擎只实现了 Ecmascript 5.1。这是一个扩展 node.js 现在必须单独实现。它将在 V8 in Q3 中可用,因此可能稍后您可以在 node.js 中使用它。

    这专注于输出,但我将如何将其用于输入?有没有 将构造函数中的时区传递给 Date 对象的方法?一世 尝试了以下方法:

    没有关于在规范中输入日期的内容。我个人看不出这会有什么用,如果你不传输 UTC 时间戳,你就做错了,因为在从 DST 到标准时间的转换过程中,"2013-01-01 12:34:56 America/New_York" 之类的东西是模棱两可的。

    这篇文章中描述的问题是由 ECMAScript 中的一个缺陷造成的 5 规格,仍然会影响输出,即使正确的数据在 TZDB。

    这是输入问题,不是输出问题。同样,使用您无法影响或检测的本地时区构建日期是错误的。使用时间戳构造函数重载或Date.UTC

    我可以期待随着 IANA 发布对 TZDB 的更新,Google 是否会推送包含更改的 Chrome 更新?

    规范中没有任何内容,但我认为期望规则不会落后太多是合理的。

    【讨论】:

    • 仅供参考 - 我还发现它已在最新的 Opera 浏览器中启用。
    • @AnttiHaapala 啊哈哈,是的,就在我按下编辑键以汇总我的答案时,您还发布了一个新答案 xD
    • 例如,在美国东部时区,给定new Date(2013,2,10,2,30) - Chrome 将其倒回至 1:30,而 IE 将其提前至 3:30。最好的实现将采用本地时间、时区和偏移量。所以一个完全明确的输入可能类似于new Date("2013-11-03T01:00:00-04:00","America/New_York")
    • 另外,虽然您提供的链接说 IE11 应该支持“没有变化”的规范 - 显然它没有在测试版中完全实现。至少,当我尝试第一个样本时(在我的问题中),我收到一个错误Option value 'AMERICA/NEW_YORK' for 'timeZone' is outside of valid range. Expected: ['UTC']
    • 规范的第 1 版假设只支持 UTC 和您自己的时区,因为没有就时区应该如何工作达成一致(实际上,Chrome 的时区实现有点奇怪)。只有在“特定情况”下才允许支持他人。不过,规范的第 2 版将正确支持它们:wiki.ecmascript.org/…
    【解决方案2】:

    这是新标准的一部分吗?也许埋在 ECMAScript 的某个地方 6?还是只是 Chrome 的自定义功能?

    确实,它是新 ECMA-402 标准的一部分。标准很难读,但是有this friendly introduction

    为什么只有谷歌浏览器?它在其他任何地方都支持吗?有没有计划 在其他任何地方都支持它?

    MDN has a list of supporting browsers。根据Bug 853301,它将在 Firefox 25 中可用。

    我检查了使用 Chrome 的 JavaScript 运行时的 node.js,但它在那里不起作用。为什么不呢?

    可能的原因有很多;它不符合当前的代码库,否则会使 node.js 变得更大更慢(Mozilla 之前的错误跟踪器条目表明时区数据使 Firefox 的下载大小增加了 10%,并导致 I/O在浏览器启动期间大幅增加。

    是否可以通过我列出的函数以外的任何其他方式访问时区数据?如果只是
    格式化字符串时可用,然后根据结果进行任何计算 困难。

    似乎不可用。此外,Intl API Primer 提到,绝对需要支持 UTC 和本地时区。

    这专注于输出,但我将如何将其用于输入?有没有办法通过 Date 对象的构造函数中的时区?我尝试了以下方法:

    Intl API 仅涉及日期/时间格式、字符串排序规则和数字格式。日期时间格式不仅支持公历,还支持多种其他历法,农历、阴阳历等。

    这篇文章中描述的问题是由 ECMAScript 5 规范中的一个缺陷造成的,它仍然会影响 输出,即使正确的数据在 TZDB 中。怎么又旧又新 实现是共存的?人们会认为这将是所有旧方式,或者所有新方式 大大地。例如,我的计算机时区设置为美国东部时间:

    new Date(2004,10,7,0,0).toLocaleString("en-US",{timeZone:"America/New_York"})

    返回“2004 年 11 月 6 日晚上 11:00:00”。它应该返回午夜,因为我从午夜开始并且 > 我的本地时区与输出时区匹配。但由于 ES5 问题,它将提供的输入日期置于 > 错误的 UTC 点。

    这样做的原因是 ES5 要求使用当前 DST 和偏移量计算新 Date 的输入,即它是美国/纽约,但具有 EDT 时区,即使 11 月 6 日不在 EDT 中。显然,由于这是如此指定,因此无法更改。但是,由于 Chrome 使用 TZDB 进行从纯 UTC 时间点值到美国/纽约 tz 的转换,因此它确实将时间视为美国东部标准时间。

    我可以期待随着 IANA 发布 TZDB 更新,Google 会推送 Chrome 更新吗? 包含更改?

    我相信

    【讨论】:

    • 我将赏金奖励给 Esailija,因为他首先回答。不过非常感谢!如果您了解任何更新,请返回此处进行编辑。如果您在此过程中发现任何其他有趣的事情,我将考虑第二次赏金。谢谢!
    猜你喜欢
    • 1970-01-01
    • 2011-12-02
    • 2018-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-04-23
    • 2019-12-23
    相关资源
    最近更新 更多