Chrome中Date.toLocaleString()的timeZone选项

34

我最近发现了一种新的JavaScript扩展。它为toLocaleStringtoLocaleDateStringtoLocaleTimeString函数添加了一些特性,这些特性是针对Date对象的。参考链接在这里

我特别感兴趣的是timeZone选项,它支持IANA/Olson时区,例如America/New_YorkEurope/London目前只有Google Chrome支持该选项

以前的建议是,如果要在JavaScript中使用UTC或其他时区而不是本地时区,则必须使用库。但现在,它似乎开始直接整合到浏览器中了。因此,现在你可以这样做:

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自定义的东西?
  • 为什么只限于Google 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"})

两种方法都没有奏效。我在规范中找不到任何内容,因此我认为这种情况不存在(尚未出现),但如果我错了,请告诉我。

  • 这篇文章中描述的问题由ECMAScript 5规范中的缺陷引起,即使TZDB中有正确的数据,该问题仍会影响输出。为什么新旧实现都能共存呢?人们可能会认为应该全部采用旧方式或新方式。例如,将我的计算机时区设置为美国东部时间:

  • 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更新吗?

  • 2个回答

    27

    更新

    这里有一篇关于API的相当详细的文章 here


    您好,以下是翻译内容:

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

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

    为什么只有Google Chrome?它在其他地方有支持吗?是否有计划在其他地方提供支持?

    近年来,Google Chrome 大多数情况下都是第一个实现新功能的浏览器。Mozilla 更为保守,例如仍在讨论是否要实现 a 元素的 download 属性。该属性现在已经在 IE11 BetaOpera 中可用,并将在 Firefox 25 中可用。

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

    Node.js只是使用与Google Chrome浏览器分开的项目相同的引擎。该引擎仅实现Ecmascript 5.1。目前,这是node.js需要单独实现的扩展。它将在Q3的V8中可用,因此可能稍后您可以在node.js中使用它。

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

    规范中没有关于输入日期的内容。如果您没有传输UTC时间戳,则我个人认为这样做是错误的,因为类似 "2013-01-01 12:34:56 America/New_York" 的东西在从夏令时到标准时间的转换期间是不明确的。

    此帖子中描述的问题是由ECMAScript 5规范中的缺陷创建的,即使TZDB中存在正确的数据,它仍会影响输出。

    这是一个输入问题,而不是输出问题。再次强调,构建一个带有本地时区的日期,你无法影响或检测到,这是错误的做法。使用时间戳构造函数重载或 Date.UTC

    我能期望当 IANA 发布 TZDB 更新时,Google 会发布包含这些更改的 Chrome 更新吗?

    规范中没有说明,但我认为可以合理地期望规则不会太滞后。

    顺便说一下-我发现在最新版本的Opera浏览器中也启用了它。 - Matt Johnson-Pint
    2
    例如,在美国东部时区,给定 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") 的东西。 - Matt Johnson-Pint
    1
    此外,虽然您提供的链接表示IE11应支持规范“没有变化”-但显然它在测试版中并未完全实现。至少,当我尝试第一个示例(在我的问题中)时,会出现错误Option value 'AMERICA/NEW_YORK' for 'timeZone' is outside of valid range. Expected: ['UTC'] - Matt Johnson-Pint
    @MattJohnson 如果你还没有看过的话,可以查看http://generatedcontent.org/post/59403168016/esintlapi。 - Esailija
    1
    规范的第一版只支持UTC和您自己的时区,因为对于时区应该如何工作没有达成一致意见(实际上,Chrome的时区实现有点奇怪)。仅在“特定情况”下允许支持其他时区。规范的第二版将正确地支持它们:http://wiki.ecmascript.org/doku.php?id=globalization:specification_drafts - David Storey
    显示剩余6条评论

    6

    这是新标准的一部分吗?可能埋藏在ECMAScript 6中的某个地方吗?还是只是Chrome自定义的东西?

    确实,它是ECMA-402新标准的一部分。这个标准很难阅读,但有这篇友好的介绍文章

    为什么只有Google Chrome支持?其他地方也支持吗?有计划在其他地方支持吗?

    MDN有一个支持浏览器列表。根据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"})

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

    由于ES5规定new Date的输入必须使用当前的DST和偏移量计算,因此它是在America/New York时区,但使用了EDT时区,即使Nov 6不在EDT中。显然,由于这样指定,所以它不能被改变。然而,由于Chrome使用TZDB将裸的UTC时间转换为America/New York tz,它会将时间考虑为EST。

    我能期望随着IANA发布TZDB更新,Google会推出包含更改的Chrome更新吗?

    我相信会。


    2
    我将奖励授予Esailija,因为他回答得最快。非常感谢!如果您了解任何更新,请回到这里进行编辑。如果您在此过程中发现其他有趣的事情,我会考虑第二个赏金。谢谢! - Matt Johnson-Pint

    网页内容由stack overflow 提供, 点击上面的
    可以查看英文原文,
    原文链接