JavaScript Temporal 即将到来
浏览器实验性版本已开始搭载新的 JavaScript Temporal 对象实现。这对 Web 开发者而言意义重大,因为 JavaScript 中的日期和时间处理将得到极大简化和现代化。依赖调度、国际化或时间敏感数据的应用程序将能够使用内置功能来处理高效、精确且一致的日期、时间、持续时间和日历。
虽然距离稳定的跨浏览器支持还有很长的路要走,并且实现过程中可能会有变化,但我们已可以了解 Temporal 的现状、其令人兴奋之处以及它解决的问题。为帮助您快速上手,MDN 本周新增了超过 270 页的 Temporal 文档,包含详细说明和示例。
什么是 JavaScript Temporal?
要理解 Temporal,我们可以先看 JavaScript 的 Date 对象。当 JavaScript 于 1995 年创建时,Date 对象是从 Java 早期有缺陷的 java.util.Date 实现复制而来的。Java 在 1997 年替换了该实现,但 JavaScript 近 30 年来却一直沿用相同的 API,尽管存在已知问题。
JavaScript Date 对象的主要问题包括:仅支持用户本地时间和 UTC,缺乏时区支持。此外,其解析行为非常不可靠,且 Date 本身是可变的,这可能引入难以追踪的错误。还有其他问题,如跨夏令时(DST)和历史日历变更的计算,这些 notoriously 难以处理。所有这些问题使得在 JavaScript 中处理日期和时间变得复杂且容易出错,对某些系统可能造成严重后果。
大多数开发者依赖专门的库(如 Moment.js 和 date-fns)来更好地处理应用程序中的日期和时间。Temporal 被设计为 Date 对象的完全替代品,使日期和时间管理可靠且可预测。Temporal 增加了对时区和日历表示的支持,以及许多用于转换、比较和计算、格式化等内置方法。API 表面有超过 200 个实用方法,您可以在 MDN 的 Temporal 文档中找到所有相关信息。
核心概念
在 Temporal 中,关键概念包括时刻(历史上的唯一点)、挂钟时间(区域时间)和持续时间。API 具有以下整体结构来处理这些概念:
- Duration: Temporal.Duration 表示两个时间点之间的差异
- 时间点:
- 唯一点时间:
- 作为时间戳: Temporal.Instant
- 带时区的日期时间: Temporal.ZonedDateTime
- 无时区意识的日期/时间(“Plain”):
- 完整日期和时间: Temporal.PlainDateTime
- 仅日期: Temporal.PlainDate
- 年和月: Temporal.PlainYearMonth
- 月和日: Temporal.PlainMonthDay
- 仅时间: Temporal.PlainTime
- 唯一点时间:
- 当前时间: 使用 Temporal.now 获取当前时间作为各种类实例,或特定格式
Temporal 示例
Temporal 的一些最基本用法包括将当前日期和时间作为 ISO 字符串获取,但从下面的示例中我们可以看到,现在可以在许多方法中提供时区,这处理了您可能自己进行的复杂计算:
处理不同的日历也得到简化,例如,可以在公历以外的日历系统(如希伯来历、中国农历和伊斯兰历)中创建日期。以下代码帮助您找出下一个中国新年是什么时候(很快就要到了!):
处理 Unix 时间戳是一个非常常见的用例,因为许多系统(API、数据库)使用该格式表示时间。以下示例展示如何获取以毫秒为单位的 Unix 时间戳,从中创建瞬间,使用 Temporal.Now 获取当前时间,然后计算距离 Unix 时间戳还有多少小时:
目前,在 Firefox 实现中,toLocaleString 不会输出区域设置敏感的字符串,因此上面的持续时间(PT31600H)以非区域设置敏感的持续时间格式返回。这可能会改变,因为这更多是设计决策而非技术限制,因为格式化持续时间是可能的,因此 polyfill 和 Firefox 实现最终可能会趋同。
有很多值得强调的地方,但我觉得 API 中一个有趣的模式是 compare() 方法,它允许您以优雅高效的方式对持续时间进行排序:
尝试 Temporal 和浏览器支持
支持正逐渐包含在实验性浏览器版本中,目前 Firefox 似乎拥有最成熟的实现。在 Firefox 中,Temporal 正在构建到 Nightly 版本中,位于 javascript.options.experimental.temporal 偏好设置后。如果您想了解完整的兼容性情况,可以查看(相当庞大的)Temporal 对象浏览器兼容性部分。
以下是跟踪 Temporal 实现的主要浏览器错误:
- Firefox: 默认在 Nightly 中构建 temporal
- Safari: [JSC] 实现 Temporal
- Chrome: 实现 Temporal 提案
此外,您可以访问 https://tc39.es/proposal-temporal/docs/,该网站提供 @js-temporal/polyfill。这意味着您可以在任何浏览器中打开 TC39 文档页面的开发者工具,并在控制台中尝试一些示例,而无需更改标志或偏好设置。
随着实验性实现的落地,现在是尝试 Temporal 并熟悉将成为 JavaScript 中处理日期和时间的现代方法的好时机。
致谢
感谢 Eric Meyer 关于该主题的工作。自从 Eric 努力记录浏览器兼容性数据并在其 mdn/content 分支中搭建文档以来,已经过去了大约 4 年。感谢 Joshua Chen 从 Eric 手中接过接力棒,并为 MDN 文档整理了一个拉取请求。感谢 André Bargull 在 Firefox Temporal 实现方面的工作。
参见
- Fixing JavaScript Date – Getting Started by Maggie Pint (2017)