迎接春天:向前拨快 Web 上的历史日期和时间
迎接春天:向前拨快 Web 上的历史日期和时间
Web 开发人员希望创建全球通用的应用程序,以便惠及世界各地的用户。Internet Explorer 10 为 Web 开发人员带来了历史性的夏令时功能,这项功能已在基础操作系统上应用。该功能使应用和站点能够跨越各种时区,与历史日期和时间更准确地进行交互。
今年早些时候,我们探讨了新兴的 ECMAScript 国际化 API,它实现了在 Web 标准平台中进行货币表示和受区域设置影响的字符串比较,这些均是需要本机互操作性或使用插件的应用场景。沿袭使 Web 平台成为全球通用平台这一共同主题,我们发布了一份演示,介绍浏览器如何与历史日期和时区信息进行交互。
历史日期和时间计算难点
在与历史日期交互(比如解释历史股价、生日或历史事件)时,Web 开发人员通常必须在服务器上执行验证。开发人员必须依赖服务器的原因在于,当前由 JavaScript 引擎对日期进行的夏令时调整,并不像通常在 .NET、PHP/Perl 和 Java 等服务器上运行的平台一样准确。除了历史 JavaScript 日期不准确之外,它们还常常不能在浏览器平台中互操作。因此,开发人员无法可靠地依赖 JavaScript 中生成的夏令时 (DST) 调整日期。
IE10 是首款具有更准确 DST 调整日期的浏览器,符合对 ECMAScript 6 草案规范第 15.9.1.8 节所作的变更。我们根据 Web 开发人员必须与服务器交互才能满足需要的应用场景,扩展了 Web 平台的功能。我们关注 JavaScript 引擎如何诠释历史日期和进行 DST 调整。我们注意到,ECMAScript 标准规范中的一个缺点是妨碍现有 JavaScript 实施在调整夏令时方面变得更准确。我们与 ECMAScript 标准委员会协商,建议对规范作出变更,以便更清晰地勾画 ECMAScript 规范未来的前景。
观看体验演示
为了说明这一问题和了解您喜爱的浏览器如何处理历史日期,您可以通过单击演示底部的任意航空航天历史事件图标,播放历史日期体验演示。在执行此操作时,浏览器读取发生事件的历史日期,并通过应用浏览器在发生事件时默认的夏令时规则来显示日期和时间。然后,演示将验证历史日期和夏令时是否正确。
在上面的案例中,当查看发射 IMAGE 航天器的历史日期时,在太平洋标准时区的 Windows 8 机器上运行的 IE10 便能够准确地确定该历史事件的正确日期和夏令时时间。
注意:夏令时并不适用于所有时区,而且存在夏令时规则从未发生更改的时区。在您的系统当前处于这种时区的情况下,我们建议您将系统的时区更改为存在夏令时规则的时区,而且已经更改了一段时间(比如太平洋标准时间),然后重新运行演示。虽然 IE10 会立即采用系统时区更改,但在您使用任何其他浏览器的情况下,可能需要重新启动浏览器才能使更新的时区生效。
提高 IE10 中的历史日期和时间处理能力
现在,让我们进一步了解一下现行 ECMAScript 规范如何影响 JavaScript 中夏令时日期调整的准确性。
ECMAScript 5.1 第 15.9.1.8 节规定,JavaScript 实施(比如 Internet Explorer 的 Chakra 引擎)应在处理历史日期时遵循以下规则:
ECMAScript 的实施不得尝试确定准确的时间是否遵从夏令时制,而只是确定在当时已经使用现行夏令时算法时,夏令时是否已经生效。这可以避免各种复杂情况,例如考虑区域设置遵守全年夏令时制的年份。
如果主机环境具有确定夏令时的功能,则 ECMAScript 的实施可以任意地将有问题的年份与主机环境为之提供夏令时信息的类似年份(具有相同闰年和相同起始工作日的年份)相映射。唯一的限制在于所有类似年份应产生相同的结果。
简而言之,这意味着要处理历史日期,JavaScript 实施应向日期应用现行夏令时算法,或者确定一年中的 1 月 1 日,计算当年是否是闰年,查找具有相同属性(起始日和闰年)年份的现行夏令时规则,然后向该历史日期应用特定的夏令时。后者的一个例子是,1972 年是从星期六开始的闰年。而且,下一个从星期六开始的闰年是 2000 年。根据语言规范,JavaScript 实施在操控 1972 年的任何日期时,可以为 2000 年使用现行规则,也可以使用夏令时规则。
在使用上面的任何一种规则时,向历史日期应用夏令时规则存在两个关键问题。首先,特定时区的夏令时规则并非一成不变,会随着时间而变化。这可能导致向历史日期应用错误的规则。其次,对于夏令时规则已经更改了一段时间的时区,Web 应用程序不再能够保持运行这些应用程序的操作系统平台所计算的历史日期的平等性,这常常迫使开发人员盲目处理 Web 应用程序和运行应用程序的平台之间的这些互操作性问题。
正如我们上面了解的那样,ECMAScript 5.1 规范文本第 15.9.1.8 节虽然允许实施方案存在像对于夏令时调整那样的错误,但还约束这些实施方案应努力达到的正确程度。这在某种程度上有违直觉,而且在实践中,没有成功地在浏览器之间达成共识。规范应摆脱对 DaylightSavingsTA 实施的依赖,则非约束如第 15.9.1.8 节中所描述的时区偏差行为。
我们的测试显示,没有任何现有的浏览器实施(最新版本)完全遵从平台标准中指定的行为,在处理日期时,也不能准确地进行夏令时调整。下面的一些示例显示了美国太平洋时区的差异:
日期 | Windows | Debian | Mac | |||||||
IE9 | Chrome | Firefox | Opera | Safari | Node | Node | Chrome | Firefox | Safari | |
4/1/2000 | 420 | 420 | 420 | 420 | 420 | 420 | 480 | 480 | 480 | 420 |
请注意,对于此日期,Chrome、FireFox 和 Node 在操作系统之间并不一致。几乎每一项实际上都是错误的,实际的 DST 调整值是 480。
日期 | Windows | Debian | Mac | |||||||
IE9 | Chrome | Firefox | Opera | Safari | Node | Node | Chrome | Firefox | Safari | |
3/10/2011 | 480 | 480 | 480 | 480 | 480 | 480 | 480 | 480 | 480 | 480 |
3/10/2109 | 480 | 480 | 480 | 480 | 420 | 480 | 480 | 480 | 420 | 420 |
请注意,对于此日期,一些环境再次违反了 ES5.1 规划(这两个年份均从星期二开始,而且都不是闰年),但在这里,即使是在单一的操作系统(Windows 和 Mac)上,仍然存在不一致。
展望未来
如今,从 Internet Explorer 10 开始,Chakra 引擎使用从运行浏览器的 Windows 平台获取的夏令时信息,在本地时间和 UTC 之间进行转换。
我们报告了规范问题,并与 ECMAScript 标准委员会协商,以便更清晰地勾画 ECMAScript 规范未来的前景,从而使 Web 平台能够实现互操作,而且更加准确。之后发布的 ECMAScript 6 规范的最新草案详细说明了如何增强和准确支持夏令时规则,并将其应用于日期,从而生成更准确的信息。IE10 是首款符合最新规范的浏览器,我们希望其他浏览器在未来版本中同样增强支持功能,以便解决各种问题,使 Web 开发人员能够创建全球通用的丰富应用程序。
随着 Web 平台重要性的持续增长,JavaScript 中常常完整地编写了丰富的应用程序逻辑,包括日历应用程序、电子表格、项目管理软件等使用的逻辑。为了使开发人员能够保持兼容性,仅在 IT10 的标准模式中启用了这一更改。在 Web 应用程序中计算历史日期和让自定义逻辑解决浏览器的误差问题情况下,您可能需要确保在升级 Web 应用程序以使用 IE10 之时,自定义逻辑仍然能够正常工作。
-- JavaScript 团队项目经理 Suresh Jayabalan