JavaScript Temporal API

在 JavaScript 的歷史中,Date 物件一直是被開發者詬病最多的部分之一。它不僅語法混亂(例如月份從 0 開始)、不支援時區轉換,而且它是「可變的」(Mutable),容易造成難以追蹤的 Bug。

為了徹底解決這些問題,新的 Temporal API 應運而生。雖然截至 2024 年底它仍處於提案階段 (Stage 3),但它代表了 JavaScript 處理日期與時間的未來方向。

為什麼需要 Temporal?

  1. 不可變性 (Immutability): 所有的 Temporal 物件都是不可變的,對日期進行操作(如加減一天)會回傳一個新的物件,而不會改動原有的。
  2. 時區與日光節約時間: 原生支援 IANA 時區,不再需要像 moment.js 這樣的龐大套件。
  3. 更精確的 API: 區分了「日期」(Date)、「時間」(Time)、「日期與時間」(DateTime) 等不同層級,讓語意更明確。
  4. 易用的加減運算: 移除繁瑣的 setFullYear() 等方法,改用 add()subtract()

基本用法

注意:在瀏覽器全面原生支援之前,你可能需要使用 Polyfill 來搶先體驗。

取得當前時間

// 取得當前的精確時間
const now = Temporal.Now.zonedDateTimeISO();
console.log(now.toString()); // 包含時區的完整時間

// 取得目前的純日期
const today = Temporal.Now.plainDateISO();
console.log(today.toString()); // 例如 "2025-01-02"

日期運算

在 Temporal 中,運算變得非常直覺:

const birthday = Temporal.PlainDate.from('1995-12-07');
const nextBirthday = birthday.add({ years: 1 });

console.log(nextBirthday.toString()); // "1996-12-07"

持續時間 (Duration)

計算兩個日期相差多久:

const d1 = Temporal.PlainDate.from('2025-01-01');
const d2 = Temporal.PlainDate.from('2025-12-25');

const diff = d1.until(d2);
console.log(diff.days); // 358

常見的類別

類別用途
Temporal.PlainDate只有日期(年、月、日),無時間。
Temporal.PlainTime只有時間(時、分、秒),無日期。
Temporal.PlainDateTime日期與時間,但不包含時區資訊。
Temporal.ZonedDateTime包含時區資訊的完整日期時間。
Temporal.Duration表示一段時間長度(如:3 小時 45 分鐘)。

總結

Temporal API 是 JavaScript 補完計畫中極為重要的一環。它將日期處理由原本的「痛苦」轉變為「優雅」。在 2025 年的開發中,了解並開始採用 Temporal(配合 Polyfill)將會讓你的程式碼更加穩健、易讀。