Temporal Polyfill logo

Temporal Polyfill

JavaScript Temporal API 的 Polyfill 实现——ES2026 标准中原生的现代日期时间 API,旨在彻底替代有缺陷的 Date 对象。

日期时间JavaScriptES2026TC39

Temporal 是 JavaScript 语言级别的新一代日期时间 API,2026 年 3 月达到 TC39 Stage 4 成为 ES2026 标准。提供不可变对象、纳秒精度、原生时区和多日历系统支持,temporal-polyfill 在浏览器原生支持全面铺开前提供生产可用的过渡方案。

Temporal Polyfill

JavaScript Temporal API 的 Polyfill 实现——ES2026 标准中原生的现代日期时间 API,旨在彻底替代有缺陷的 Date 对象。

技术简介说明

Temporal 是 JavaScript 语言级别的新一代日期时间 API,于 2026 年 3 月达到 TC39 Stage 4,正式成为 ES2026 标准的一部分。它经历了约 9 年的提案演进,旨在彻底解决 JavaScript 原始 Date 对象的根本性缺陷——可变性、缺少时区支持、月份从 0 开始计数、无法安全表示纯日期等。

Temporal 作为语言内置的全局命名空间(类似 IntlMath),提供了不可变的、类型安全的日期时间操作。它原生支持时区、日历系统、纳秒精度时间戳,并且 API 设计充分考虑了 DST(夏令时)安全。

在浏览器原生支持全面铺开之前,temporal-polyfill@js-temporal/polyfill 提供了生产可用的 Polyfill 实现,使开发者可以提前使用 Temporal API。随着 Chrome 144+ 和 Firefox 139+ 已经原生支持 Temporal,Polyfill 主要用于兼容旧浏览器和作为过渡方案。

基本信息

项目详情
官网/规范https://tc39.es/proposal-temporal/docs/
MDN 文档https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Temporal
GitHub(提案)https://github.com/tc39/proposal-temporal
Polyfill(temporal-polyfill)https://www.npmjs.com/package/temporal-polyfill
Polyfill(@js-temporal/polyfill)https://www.npmjs.com/package/@js-temporal/polyfill
LicenseMIT
最新版本temporal-polyfill v1.0.1(2026 年)
标准状态ES2026 标准(TC39 Stage 4,2026 年 3 月)
主要推动者Google(V8 团队)、Bloomberg、Igalia、Mozilla

快速上手

安装

# 轻量级 Polyfill(推荐,~19.8KB gzipped)
npm install temporal-polyfill
 
# 官方完整 Polyfill(Alpha 阶段,体积较大)
npm install @js-temporal/polyfill
 
# CDN(temporal-polyfill)
<script src="https://cdn.jsdelivr.net/npm/temporal-polyfill/global.min.js"></script>

基础配置

// temporal-polyfill(推荐)
import { Temporal } from 'temporal-polyfill'
 
// @js-temporal/polyfill
import { Temporal } from '@js-temporal/polyfill'
 
// 检测是否需要 Polyfill(条件加载)
const TemporalNS = globalThis.Temporal || (await import('temporal-polyfill')).Temporal

最小示例

import { Temporal } from 'temporal-polyfill'
 
// 当前时间(纳秒精度)
const now = Temporal.Now.instant()
console.log(now.toString()) // '2026-07-07T06:30:00.123456789Z'
 
// 本地日期
const today = Temporal.Now.plainDateISO()
console.log(today.toString()) // '2026-07-07'
 
// 带时区的日期时间
const zoned = Temporal.Now.zonedDateTimeISO()
console.log(zoned.toString()) // '2026-07-07T14:30:00+08:00[Asia/Shanghai]'
 
// 日期计算
const tomorrow = today.add({ days: 1 })
 
// 时间差(Duration)
const diff = tomorrow.until(today)
console.log(diff.toString()) // '-PT24H'
 
// 格式化
console.log(zoned.toLocaleString('zh-CN', {
  dateStyle: 'full',
  timeStyle: 'long'
})) // '2026年7月7日星期一 下午2:30:00 [Asia/Shanghai]'

核心概念与架构

设计哲学

Temporal 的核心设计原则:

  1. 不可变:所有操作返回新对象,原始对象永不改变
  2. 显式优于隐式:时区转换必须显式指定,不依赖全局状态
  3. 类型安全:不同概念使用不同对象类型,避免语义混淆
  4. 纳秒精度:内部使用纳秒级时间戳,满足高精度场景
  5. DST 安全:API 设计考虑了夏令时边界情况

核心对象体系

Temporal 定义了一套完整的对象类型,按语义精确分类:

对象语义示例
Temporal.Instant时间线上的精确时间点(UTC 纳秒)2026-07-07T06:30:00Z
Temporal.ZonedDateTime带时区的日期时间2026-07-07T14:30:00+08:00[Asia/Shanghai]
Temporal.PlainDateTime不带时区的日期时间2026-07-07T14:30:00
Temporal.PlainDate纯日期(无时间)2026-07-07
Temporal.PlainTime纯时间(无日期)14:30:00
Temporal.PlainYearMonth年月(如信用卡有效期)2026-07
Temporal.PlainMonthDay月日(如生日)07-07
Temporal.Duration时间跨度P1Y2M3DT4H5M6S
Temporal.Now获取当前时间的工具对象Temporal.Now.instant()
Temporal.TimeZone时区抽象Temporal.TimeZone.from('Asia/Shanghai')
Temporal.Calendar日历系统抽象Temporal.Calendar.from('iso8601')

类型分离的价值

传统 Date 对象将"日期"和"带时区的时间"混为一谈。Temporal 通过类型分离解决了这个问题:

// ❌ Date 对象的歧义
const d = new Date('2026-07-07')
// 这是 UTC 的 7 月 7 日还是本地的 7 月 7 日?
 
// ✅ Temporal 的精确语义
const plainDate = Temporal.PlainDate.from('2026-07-07')      // 明确:纯日期
const zoned = Temporal.ZonedDateTime.from('2026-07-07T00:00:00[Asia/Shanghai]') // 明确:带时区

核心特性

  • ES2026 标准:TC39 Stage 4,语言级别的日期时间解决方案
  • 不可变设计:所有对象创建后不可修改
  • 纳秒精度:内部使用 BigInt 存储纳秒级时间戳
  • 原生时区支持:IANA 时区数据库集成,无需额外数据文件
  • 日历系统支持:原生支持非格里高利日历(伊斯兰历、佛历、希伯来历等)
  • DST 安全:API 设计显式处理夏令时边界
  • 类型安全:11 种精确类型,消除日期语义歧义
  • 国际化友好:与 Intl API 深度集成,支持 toLocaleString
  • 链式且可组合instant.toZonedDateTimeISO('Asia/Shanghai').toPlainDate()
  • Duration 运算:支持日历感知的 duration 运算(考虑闰年、月份天数)

生态图

Polyfill 方案

包名状态体积说明
temporal-polyfillBeta/v1.0.1~19.8KB gzipped轻量级,适合生产环境
@js-temporal/polyfillAlpha~60KB+官方完整实现,功能更全面

浏览器原生支持进度(2026 年中)

浏览器支持状态
Chrome 144+✅ 原生支持
Firefox 139+✅ 原生支持
Safari🟡 Technical Preview 中大部分可用
Edge🟡 Beta 实验性支持
Node.js🟡 Flag 后可用
Deno🟡 部分支持
Bun🟡 部分支持

相关生态

  • Intl API:Temporal 与 Intl.DateTimeFormat 深度集成
  • TypeScript 类型@types/temporal 或内置类型定义
  • 迁移工具:从 Date/Moment.js/date-fns 迁移到 Temporal 的指南和 codemod

关键依赖

Temporal 作为语言内置 API,无外部依赖。Polyfill 同样零外部依赖。

适用场景

  • 新项目的首选日期方案:2026 年新项目应优先考虑使用 Temporal API(原生或 Polyfill)
  • 需要高精度时间戳:日志、监控、科学计算等需要纳秒精度的场景
  • 复杂时区处理:全球化应用、跨时区日程安排
  • 非格里高利日历:需要支持伊斯兰历、佛历、希伯来历的应用
  • 替代 Moment.js/date-fns/Luxon:Temporal 的完整功能集可以替代所有第三方日期库
  • 服务端日期处理:Node.js 环境下的精确日期运算
  • 未来保障:使用语言标准意味着不需要依赖第三方库的维护状态

开发与工程化

条件加载 Polyfill

// 推荐:仅在浏览器不支持时加载 Polyfill
const loadTemporal = async () => {
  if (globalThis.Temporal) return globalThis.Temporal
  const { Temporal } = await import('temporal-polyfill')
  return Temporal
}
 
const Temporal = await loadTemporal()

Webpack/Vite 配置

// webpack.config.js - 条件加载
module.exports = {
  // 无需特殊配置,使用动态 import 即可
}
 
// vite.config.js
// Vite 原生支持动态 import,无需额外配置

测试

// Vitest / Jest 中使用 Temporal
import { Temporal } from 'temporal-polyfill'
 
// 固定时间进行测试
const mockNow = Temporal.ZonedDateTime.from('2026-07-07T14:30:00[Asia/Shanghai]')
 
// 使用 Temporal.Now 的 mock 能力
// 注意:Temporal.Now 不能被直接 mock,需要传入具体值替代

CI/CD 集成

Temporal 作为标准 API,在 CI/CD 中无需特殊配置。但需注意 Node.js 版本的 Temporal 支持状态。

性能与安全

性能特点

  • 解析速度:基准测试显示 Temporal 实现已匹配或超过原生 Date 对象
  • 内存效率:不可变设计 + 纳秒精度使用 BigInt,内存占用略高于 Date
  • 包体积:原生支持时无额外体积;Polyfill(temporal-polyfill)约 19.8KB gzipped

与第三方库性能对比

在主流浏览器中,Temporal 的性能已经可以匹配甚至超过第三方库:

  • 解析 ISO 字符串:Temporal ≈ 原生 Date > Day.js > date-fns > Luxon
  • 日期计算:Temporal ≈ date-fns > Day.js > Luxon

安全注意事项

  • Temporal 是语言内置 API,攻击面极小
  • Polyfill 由 TC39 提案团队维护,代码质量有保障
  • 用户输入的日期字符串仍应通过 Temporal.PlainDate.from() 的异常处理进行校验

技术对比

特性TemporalDay.jsdate-fnsLuxonMoment.js
类型语言标准第三方库第三方库第三方库第三方库
浏览器支持Chrome 144+(2026)所有所有所有所有
不可变
时区✅ 原生插件@date-fns/tz✅ Intlmoment-timezone
日历系统✅ 多日历✅ Intl
纳秒精度毫秒毫秒毫秒毫秒
Tree-shakingN/A(内置)
包体积0(原生)2KB~17.5KB~53KB~72KB
类型数量11 种精确类型1 种N/A(函数)3 种1 种
维护方TC39 / 浏览器厂商社区社区Moment 团队维护模式
DST 安全部分

Temporal 的独特优势

  1. 语言标准:不依赖任何第三方库,随浏览器和 Node.js 版本升级
  2. 类型精确:11 种对象类型消除了日期语义歧义
  3. 纳秒精度:唯一提供纳秒级精度的方案
  4. 多日历支持:唯一原生支持非格里高利日历的方案

最佳实践

推荐模式

// ✅ 使用条件加载模式
const Temporal = globalThis.Temporal ||
  (await import('temporal-polyfill')).Temporal
 
// ✅ 优先使用 ZonedDateTime 处理带时区的场景
const meeting = Temporal.ZonedDateTime.from({
  year: 2026, month: 7, day: 7,
  hour: 14, minute: 30,
  timeZone: 'Asia/Shanghai'
})
 
// ✅ 使用 PlainDate 处理纯日期
const birthday = Temporal.PlainDate.from({ month: 7, day: 7 })
 
// ✅ 使用 Duration 进行精确的时间差计算
const diff = meeting.until(otherMeeting, { largestUnit: 'hours' })
 
// ✅ 使用 Temporal.Now 获取当前时间
const now = Temporal.Now.instant()
const todayLocal = Temporal.Now.plainDateISO()
 
// ✅ 替代 Date.now()
const timestamp = Temporal.Now.instant().epochMilliseconds

常见陷阱

  • Temporal.Now 不可 mock:测试中无法直接 mock Temporal.Now,需要传入具体值
  • Polyfill 体积:temporal-polyfill 约 19.8KB,虽然轻量但仍需考虑
  • 浏览器支持不完整:Safari 和 Node.js 的支持仍在进行中,生产环境需要 Polyfill
  • PlainDate vs ZonedDateTime:选择正确的类型很重要,混用可能导致意外行为
  • Duration 的 ISO 格式:Duration 使用 ISO 8601 格式(P1Y2M3DT4H5M6S),学习成本较高
  • 两个 Polyfill 的选择temporal-polyfill 更轻量,@js-temporal/polyfill 功能更全但仍在 Alpha

技术局限与边界

  • 浏览器支持仍在推进:Chrome 144+ 和 Firefox 139+ 已支持,但 Safari 和 Node.js 仍在完善中
  • Polyfill 非 100% 完整:Polyfill 可能无法覆盖所有边界情况
  • 生态不成熟:Temporal 刚进入标准,第三方库、教程、工具链不如 Moment.js/date-fns 丰富
  • 学习曲线:11 种对象类型的概念体系需要时间学习
  • 迁移成本:从现有 Date/Moment.js 代码迁移到 Temporal 需要大量重构
  • Node.js 支持滞后:Node.js 中 Temporal 仍需要 flag 启用,服务端使用受限
  • API 复杂度:对于简单的日期格式化场景,Temporal 可能"过度设计"
  • 两个 Polyfill 并行:社区分裂为两个 Polyfill 实现,选择时可能困惑

学习资源

2026 年现状

标准状态

  • ES2026 标准:2026 年 3 月达到 TC39 Stage 4,正式成为 JavaScript 标准
  • 这是 JavaScript 日期处理领域 9 年努力的里程碑

浏览器支持

  • Chrome 144+:✅ 原生支持(2026 年 1 月)
  • Firefox 139+:✅ 原生支持(2025 年 5 月)
  • Safari:🟡 Technical Preview 中大部分 API 可用
  • Edge:🟡 Beta 实验性支持
  • Node.js:🟡 需要 flag 启用
  • Deno / Bun:🟡 部分支持

Polyfill 状态

  • temporal-polyfill v1.0.1:轻量级(~19.8KB),生产可用
  • @js-temporal/polyfill:仍在 Alpha 阶段,功能更全

发展趋势

  • 2026 年是 Temporal 元年:进入标准 + 主流浏览器支持,是日期处理领域的分水岭
  • 第三方库的过渡角色:date-fns、Day.js、Luxon 可能会逐步提供 Temporal 互操作层,或定位为 Temporal 的补充
  • Moment.js 的终结者:Temporal 的完整功能集(时区、日历、不可变、纳秒精度)使得第三方日期库的必要性大幅降低
  • 渐进式迁移:在浏览器支持完全普及前(预计 2027-2028 年),Polyfill 是必要的过渡方案
  • 长期趋势:Temporal 将成为 JavaScript 日期处理的唯一标准方案,第三方日期库将逐步退出历史舞台