彻底告别 Date,TC 39 提案 Temporal API

开发 前端
JavaScript 自诞生以来,处理日期和时间一直是开发者们头疼的难题。虽然 Date​ 对象自 1990 年代就已经引入,但它的问题随着时间的推移变得愈发突出。错误的时区处理、复杂的日期操作以及闰秒、夏令时等问题,令 Date API 在复杂场景中几乎无法胜任。

Hello,大家好,我是 Sunday。

JavaScript 自诞生以来,处理日期和时间一直是开发者们头疼的难题。虽然 Date 对象自 1990 年代就已经引入,但它的问题随着时间的推移变得愈发突出。错误的时区处理、复杂的日期操作以及闰秒、夏令时等问题,令 Date API 在复杂场景中几乎无法胜任。

为了彻底解决这些历史遗留问题,TC39 提出了全新的 Temporal API,为 JavaScript 带来了现代化、精确的日期时间处理能力。

1. 现有 Date API 的问题

Date 对象“曾经”是 JavaScript 中唯一内置的日期时间处理工具。但是,它在设计上有很多缺陷:

  • 时区问题:Date 默认依赖于操作系统的时区配置,这导致不同环境下的时间处理可能不一致。
  • 不可变性的缺失:Date 对象是可变的,这意味着在操作中可能会意外修改原有对象,导致代码难以维护和调试。
  • API 不够完善:对于复杂的日期操作,比如加减月份或年份,Date 提供的接口既不直观也不够灵活,且容易出错。
  • 可能出现一些错误:Date 不能正确处理闰秒和其他复杂的时间边界问题,这在实际应用中经常引发潜在错误。

这些问题给我们带来了很多的困扰,导致我们不得不使用一些第三方的包(如:dayjs、momentjs 等)。

但是这种情况很快就要迎来变了,那就是 Temporal API!

2. Temporal API

Temporal API 的设计初衷是完全替代现有的 Date,提供一个更加精确、灵活、符合现代需求的日期时间操作工具。它通过一套全新的类和方法,重新定义了日期和时间的处理方式。

2.1 核心功能

Temporal 提供了一系列专门处理不同时间相关问题的对象和方法:

  • Temporal.PlainDate:表示没有时区的日期(如 2024-10-20)。
  • Temporal.PlainTime:表示没有时区的时间(如 14:30:00)。
  • Temporal.PlainDateTime:表示没有时区的日期和时间组合(如 2024-10-20T14:30:00)。
  • Temporal.ZonedDateTime:表示带有时区的日期和时间(如 2024-10-20T14:30:00-04:00[America/New_York])。
  • Temporal.Instant:表示唯一的、基于 UTC 的时间点,精确到纳秒(如 2024-10-20T18:30:00.000000123Z)。

这些类型互相独立,用户可以根据不同的需求选择合适的类型。例如:当只需处理日期时可以使用 PlainDate,而在处理跨时区的问题时可以使用 ZonedDateTime。

2.2 不可变性

Temporal API 的所有对象都是不可变的,每次操作返回一个新对象,不会改变原有对象。这种设计极大地提高了代码的可读性和安全性,避免了意外修改导致的难以追踪的错误。

此外,Temporal 提供了精确到纳秒的时间处理,解决了 Date 只能精确到毫秒的局限,特别适合对高精度有需求的场景。

2.3 时区与日历系统的支持

Temporal API 内置了对时区和多种日历系统的支持。我们可以方便地处理跨时区的时间转换问题,而无需依赖外部库。同时,Temporal 提供了多种日历的支持,比如:公历、佛历、伊斯兰历等,这为国际化应用程序提供了极大的便利。

3. Temporal API 的典型使用场景

以下示例来自 来自 TC39 文档:https://tc39.es/proposal-temporal/docs/

示例 1:基本日期操作

const today = Temporal.PlainDate.from('2024-10-20');
const nextWeek = today.add({ days: 7 });
console.log(nextWeek.toString());  // 输出: 2024-10-27

在这个例子中,我们创建了一个表示当前日期的 PlainDate 对象,并通过 add 方法轻松计算出一周后的日期。

示例 2:跨时区时间处理

const nyTime = Temporal.ZonedDateTime.from({
 timeZone: 'America/New_York',
 year: 2024,
 month: 10,
 day: 20,
 hour: 12
})
const tokyoTime = nyTime.withTimeZone('Asia/ShangHai')
console.log(tokyoTime.toString()) // 输出: 2024-10-21T00:00:00+08:00[Asia/Shanghai]

以上代码把纽约时间转化为北京时间('Asia/ShangHai')

示例 3:处理当前时间点

const instant = Temporal.Instant.now();
console.log(instant.toString());  // 输出: 2024-10-20T14:30:00.123456789Z

Instant 表示唯一的瞬时时间,特别适合用于日志记录、时序数据等需要精确记录时间点的场景。

4. Temporal 相比 Date 的优势

与传统的 Date API 相比,Temporal 带来了许多实质性的改进:

  1. 不变性:所有操作返回新对象,避免了潜在的数据修改问题。
  2. 精度提升:时间精度达到纳秒级别,适用于高精度需求的场景。
  3. 时区支持:内置时区转换功能,消除了手动处理时区的繁琐操作。
  4. 多日历支持:内置支持多种日历系统,适应全球化需求。
  5. 更直观的 API:Temporal API 设计更加直观,日期时间的操作变得简洁明了。

5. 如何在现有项目中使用 Temporal

因为 Temporal 是 TC39 的实验性 API(哪怕已经很接近完善了),但是我们依然无法直接在浏览器中使用它。

如果想要使用,那么必须要配合 @js-temporal/polyfill 才可以

图片图片

我们可以直接创建一个 node 项目,然后通过 npm i @js-temporal/polyfill 完成安装,然后利用require 导入 Temporal 即可使用

图片 图片

责任编辑:武晓燕 来源: 程序员Sunday
相关推荐

2021-07-30 18:35:10

JavaScript 模块代码

2022-09-21 08:00:58

JavaScriptTC39

2024-06-25 12:39:05

2023-07-17 10:21:25

TC39JavaScript

2023-11-06 07:53:36

谷歌Android应用程序

2009-09-14 09:09:07

Delphi 2010

2023-09-20 14:30:36

K8s亚马逊谷歌

2023-02-03 17:16:33

ECMAScriptAPITC39

2022-07-07 08:30:50

类型注解原生JS

2022-07-29 15:10:24

开发React

2022-09-23 13:57:11

xxl-job任务调度中间件

2023-05-09 12:08:02

FedoraLinux

2022-05-09 08:22:09

ReactHooks

2015-04-16 10:47:08

Linux计算机重启时代

2020-03-03 19:59:38

主板无线网卡

2009-02-27 09:08:43

苹果乔布斯接班人

2015-08-03 14:49:51

2014-12-22 10:14:31

Java8

2016-12-07 10:30:19

NTP网络时间协议

2023-12-22 08:13:39

业务review流程
点赞
收藏

51CTO技术栈公众号