Synth Daily

Temporal:修复 JavaScript 时间问题的 9 年征程

JavaScript 的原生 Date 对象由于 1995 年仅用 10 天仓促设计,长期以来在可变性、时区处理和日期计算方面给开发者带来了巨大痛苦。经过 TC39 委员会及多家科技公司长达九年的协作,新的 Temporal API 现已达到 Stage 4 阶段,正式成为 ES2026 标准的一部分。它通过引入不可变性、纳秒级精度以及对多时区和多日历的原生支持,彻底解决了 JavaScript 处理时间的历史遗留问题。

为什么 Date 对象必须被取代?

原生 Date 对象的设计决策在现代开发中已成为障碍,其核心痛点包括:

  • 可变性 (Mutability):Date 的修改会直接改变原对象,经常导致意外的逻辑错误。
  • 拙劣的计算逻辑: 比如 1 月 31 日加一个月,结果会静默滚动到 3 月 2 日,而非预期的 2 月底。
  • 解析模糊: 不同浏览器对非标准 ISO 字符串的解析结果(本地时间 vs UTC)不一致。
  • 缺乏时区感知: 难以优雅地处理夏令时(DST)和跨时区计算。

"1995 年,JavaScript 的创建者 Brendan Eich 为了赶进度,直接移植了 Java 的 Date 实现。当时的一致性考量,成为了后来三十年的技术债。"

Temporal 的核心改进

Temporal 不再试图用一个 API 解决所有问题,而是提供了一个包含多种专用类型的命名空间。

  • Temporal.ZonedDateTime 最全面的类型,包含确切时刻、时区和历法,能自动处理夏令时跳变。
  • Temporal.Instant 纯粹的时间点(Unix 时间戳),精度提升至纳秒级Date 仅为毫秒)。
  • Plain 系列类型:PlainDatePlainTime,它们代表“墙上时间”,不受时区干扰,适合生日、节假日等场景。
  • Temporal.Duration 专门处理时间长度的类型,支持不同单位间的转换和比较。
  • 完全不可变: 所有的计算操作(如 addsubtract)都会返回一个新的实例。

史无前例的协作模式:temporal_rs

由于 Temporal 规格极其庞大(测试用例超过 4500 个),实现难度极高。

  • 跨引擎共享: 谷歌、彭博社和 Igalia 等合作开发了基于 Rust 的共享库 temporal_rs
  • 降低门槛: 这种模式允许不同的浏览器引擎(如 V8, SpiderMonkey)共享同一套核心逻辑,确保行为高度一致。
  • 工程质量: 利用 Rust 的安全性、Lint 工具和 CI 测试,显著提升了代码的稳健性。

现状与未来集成

Temporal 已经从理论走向现实,目前的生态支持情况如下:

  • 浏览器支持: Firefox (v139)、Chrome (v144) 和 Edge (v144) 均已支持。
  • 工具链: TypeScript 6.0 Beta 已开始提供原生支持。
  • Web API 集成: 未来将进一步整合到 HTML 表单控件(如 <input type="date">valueAsPlainDate 属性)以及 Cookie 过期时间等 Web 标准中。

"近 10 年的努力,JavaScript 终于拥有了一个现代的时间 API。这一次,我们终于做对了。"