JavaScript中的Temporal Date API非常优秀,原因如下:- Apidog

作者:API传播员 · 2025-12-23 · 阅读时间:6分钟

处理日期和时间一直是JavaScript开发中的一个难题。原生的 Date 对象由于其设计上的局限性和不一致性,迫使许多开发者转向使用第三方库,如 Moment.js 或 Date-fns。然而,TC39委员会(负责JavaScript规范的制定)提出了一个全新的解决方案——Temporal API。这一现代化的日期和时间处理方法,旨在解决JavaScript中长期存在的时态操作问题。


为什么需要 Temporal API?

在深入了解 Temporal API 之前,我们先来看一下当前 Date 对象的主要问题:

  1. 可变状态Date 对象是可变的,这可能导致意外的副作用。
  2. 功能有限:简单的日期加减或比较操作需要复杂的代码。
  3. 字符串解析不一致:从字符串解析日期在不同浏览器中表现不一致。
  4. 缺乏时区支持:对 UTC 和本地时间以外的时区支持不足。
  5. 仅支持公历:无法处理其他日历系统。
  6. 混乱的 API:例如 getMonth() 方法返回的月份索引是从 0 开始的,而不是 1。

这些问题使得开发者在处理日期和时间时容易出错,也因此推动了第三方库的广泛使用。


介绍 Temporal API

Temporal API 是 JavaScript 中一个全新的全局对象(Temporal),它提供了全面、现代化的日期和时间处理功能。其设计原则包括:

  1. 不变性:所有 Temporal 对象都是不可变的,避免了副作用。
  2. 清晰性:明确区分不同类型的日期和时间概念。
  3. 时区支持:内置对所有时区的支持,包括夏令时计算。
  4. 多种日历系统:支持非公历的日历系统。
  5. 高精度:时间计算支持纳秒级精度。
  6. 一致性:标准化的日期解析和格式化方法。

Temporal API 的关键数据类型

Temporal API 引入了多种专门的类,用于处理日期和时间的不同方面:

纯数据类型(无时区信息)

  1. Temporal.PlainDate:表示仅包含日期的对象(如 2006-08-24)。
  2. Temporal.PlainTime:表示仅包含时间的对象(如 19:39)。
  3. Temporal.PlainDateTime:结合日期和时间,但不包含时区信息。
  4. Temporal.PlainYearMonth:表示特定的年份和月份(如 2020-10)。
  5. Temporal.PlainMonthDay:表示月份和日期,但不包含年份(如 07-14)。

分区数据类型(带时区信息)

  1. Temporal.ZonedDateTime:一个时区感知的日期/时间对象,表示特定时区的具体时间。
  2. Temporal.Instant:表示一个固定的时间点,与时区无关。

其他类型

  1. Temporal.Duration:表示时间间隔(如 5 分钟 30 秒)。
  2. Temporal.TimeZone:表示时区,并提供时区转换方法。
  3. Temporal.Calendar:表示日历系统。

使用 Temporal API

创建时间对象

Temporal API 提供了多种创建时间对象的方法:

// 获取当前日期和时间
const now = Temporal.Now.plainDateTimeISO();
console.log(now.toString()); // 例如:2023-08-24T14:30:45.123456789

// 获取当前日期
const today = Temporal.Now.plainDateISO();
console.log(today.toString()); // 例如:2023-08-24// 获取当前时间
const currentTime = Temporal.Now.plainTimeISO();
console.log(currentTime.toString()); // 例如:14:30:45.123456789// 从组件创建对象
const date = Temporal.PlainDate.from({ year: 2023, month: 8, day: 24 });
const time = Temporal.PlainTime.from({ hour: 14, minute: 30, second: 45 });
const dateTime = Temporal.PlainDateTime.from({ year: 2023, month: 8, day: 24, hour: 14, minute: 30, second: 45 });// 从 ISO 字符串创建对象
const dateFromString = Temporal.PlainDate.from("2023-08-24");
const timeFromString = Temporal.PlainTime.from("14:30:45");
const dateTimeFromString = Temporal.PlainDateTime.from("2023-08-24T14:30:45");

使用时区

Temporal API 提供了对时区的强大支持:

// 获取本地时区的当前时间
const localTime = Temporal.Now.zonedDateTimeISO();
console.log(localTime.toString()); // 例如:2023-08-24T14:30:45+01:00[Europe/London]

// 获取特定时区的当前时间
const tokyoTime = Temporal.Now.zonedDateTimeISO("Asia/Tokyo");
console.log(tokyoTime.toString()); // 例如:2023-08-24T22:30:45+09:00[Asia/Tokyo]// 时区之间的转换
const nyTime = localTime.withTimeZone("America/New_York");
console.log(nyTime.toString()); // 例如:2023-08-24T09:30:45-04:00[America/New_York]

时间运算

Temporal API 支持直观的时间运算:

// 添加时间
const tomorrow = today.add({ days: 1 });
const nextWeek = today.add({ days: 7 });
const twoHoursLater = currentTime.add({ hours: 2 });

// 减去时间
const yesterday = today.subtract({ days: 1 });
const lastWeek = today.subtract({ days: 7 });
const twoHoursEarlier = currentTime.subtract({ hours: 2 });// 使用持续时间
const duration = Temporal.Duration.from({ hours: 2, minutes: 30 });
const laterTime = currentTime.add(duration);// 计算两个日期之间的差异
const date1 = Temporal.PlainDate.from("2023-01-01");
const date2 = Temporal.PlainDate.from("2023-08-24");
const difference = date1.until(date2);
console.log(difference.toString()); // P236D
console.log(difference.days); // 236

修改组件

Temporal API 提供了一种干净的方法来修改时间对象的组件:

// 修改年份
const nextYear = date.with({ year: date.year + 1 });

// 设置特定组件
const newDateTime = dateTime.with({ hour: 12, minute: 0, second: 0 });
console.log(newDateTime.toString()); // 2023-08-24T12:00:00

时间比较

Temporal API 提供了直观的比较方法:

const date1 = Temporal.PlainDate.from("2023-08-24");
const date2 = Temporal.PlainDate.from("2023-09-15");

console.log(date1.equals(date2)); // false
console.log(date1.before(date2)); // true
console.log(date1.after(date2)); // false
console.log(date1.since(date2).days); // -22

当前状态与未来展望

截至目前,Temporal API 仍处于 TC39 提案的第 3 阶段,尚未被正式纳入 ECMAScript 标准。但开发者可以通过使用 @js-temporal/polyfill 来提前体验这一功能:

# 安装 polyfill
npm install @js-temporal/polyfill
// 在代码中使用
import { Temporal } from "@js-temporal/polyfill";
const now = Temporal.Now.plainDateTimeISO();

结论

Temporal API 是 JavaScript 日期和时间处理能力的一次重大飞跃。它通过解决 Date 对象的局限性,为开发者提供了更强大、更直观的工具。其主要优势包括:

  1. 不变性:避免副作用。
  2. 清晰性:明确区分日期和时间类型。
  3. 全面性:支持从简单日期到复杂时区操作。
  4. 直观性:提供易用的方法,如 add()with()
  5. 高精度:支持纳秒级别的时间计算。
  6. 全球化支持:内置多时区和多日历系统。

随着全球化和时间敏感性需求的增加,Temporal API 将成为 JavaScript 开发者工具箱中的重要组成部分。通过采用这一 API,开发者可以更高效地编写代码,提升用户体验,同时减少对第三方库的依赖。

原文链接: https://apidog.com/blog/temporal-date-api-javascript/