找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

1352

积分

0

好友

189

主题
发表于 5 天前 | 查看: 15| 回复: 0

Google Chrome 在最新版本(如Chrome 123及更高版本)中,正式启用了对 Temporal API 的支持,这标志着JavaScript原生日期时间处理能力的一次重大现代化升级。

图片

为何我们需要Temporal API?

长期以来,开发者处理日期时间主要依赖原生的 Date 对象或第三方库,但它们存在明显的局限性。

原生 Date 对象的缺陷:

  • 信息丢失:解析字符串后立即转换为时间戳,原始时区信息无法保留。
  • 时区处理复杂:时区计算容易出错,API 设计不够直观。
  • 功能单一:对多日历系统(如农历)缺乏原生支持。

主流第三方库的不足:

  • day.js:虽然轻量,但功能相对有限,同样存在时区信息处理的问题。
  • moment.js:功能全面但包体积较大,且已进入维护模式,不再添加新功能。

Temporal API 旨在成为 Date 对象的现代化、功能完备的替代方案。该提案目前处于 TC39 流程的第三阶段(Candidate),已在 MDN 发布文档,并开始在浏览器实验性版本中落地。

Temporal API的核心设计理念

1. 明确的时间类型区分

Temporal API 将时间概念进行了精细的划分,主要分为:

  • Plain 类型:表示没有时区信息的“本地时间”(例如 2025-01-27T09:35)。
  • Zoned 类型:包含明确时区标识的“绝对时间”(例如 2025-01-27T09:35+08:00[Asia/Shanghai])。

2. 严格的时区处理

与现有方案不同,Temporal 要求时区标识必须明确无误。

// ❌ 仅提供偏移量,缺少时区名称,解析失败
Temporal.ZonedDateTime.from("2025-01-27T09:35+08:00")
// RangeError: Temporal.ZonedDateTime requires a time zone ID in brackets

// ✅ 无偏移量,但有时区名称,API可自动推断
Temporal.ZonedDateTime.from("2025-01-27T09:35[Asia/Shanghai]")
// <2025-01-27T09:35:00+08:00[Asia/Shanghai]>

// ✅ 同时提供偏移量和时区名称
Temporal.ZonedDateTime.from("2025-01-27T09:35+08:00[Asia/Chongqing]")
// <2025-01-27T09:35:00+08:00[Asia/Chongqing]>

3. 多日历系统原生支持

Temporal 原生支持包括农历在内的多种日历系统,这对于需要处理国际化日期,特别是涉及数据库中存储特定文化日期数据的应用场景非常有用。

// 对比公历与农历的闰年
Temporal.Now.plainDateISO().inLeapYear // false (2025年为公历平年)
Temporal.Now.plainDateISO().withCalendar("chinese").inLeapYear // true (农历2025年置闰)

// 农历日期计算示例
const nyd = Temporal.ZonedDateTime.from("2025-01-29[Asia/Shanghai]")
const nextNyd = nyd.withCalendar('Chinese').add({ years: 1 })
// <2026-02-17T00:00:00+08:00[Asia/Shanghai][u-ca=chinese]>

Temporal API 基础使用示例

获取时间与创建对象

// 获取当前时间的瞬间(类似时间戳)
Temporal.Now.instant() // Temporal.Instant <2025-01-29T14:37:26.421844105Z>
Temporal.Now.instant().epochMilliseconds // 等价于 Date.now()

// 获取系统当前时区ID
Temporal.Now.timeZoneId() // "Asia/Shanghai"

// 创建日期时间对象
Temporal.PlainDateTime.from("2025-01-29")
Temporal.ZonedDateTime.from({
  calendar: "chinese",
  timeZone: "Asia/Shanghai",
  year: 2025,
  month: 1,
  day: 1
})

日期格式化输出

const date = Temporal.Now.zonedDateTimeISO()

// 基础ISO格式输出
date.toString({ smallestUnit: "minutes", timeZoneName: "never" })
// "2025-01-29T14:35-05:00"

// 本地化字符串格式
date.toLocaleString("zh-CN")
// "2025/1/29 GMT-5 14:35:41"

// 使用 Intl API 进行高性能格式化(推荐)
const formatter = new Intl.DateTimeFormat("zh-CN", {
  year: "numeric",
  month: "long",
  day: "numeric"
})
formatter.format(date)

日期运算与操作

// 获取指定月份的最后一天
const date = Temporal.PlainDate.from("2025-02-23")
date.with({ day: date.daysInMonth }) // 结果为 2025-02-28

// 处理农历节日(例如中秋节)
const midAutumn = Temporal.PlainMonthDay.from({
  monthCode: "M08",
  day: 15,
  calendar: "chinese"
})
const midAutumn2025 = midAutumn.toPlainDate({ year: 2025 })
// Temporal.PlainDate <2025-10-06[u-ca=chinese]>

时区转换

const current = Temporal.Now.zonedDateTimeISO()
current.withTimeZone("Asia/Shanghai").toLocaleString("zh-CN")
// "2025/1/30 GMT+8 5:42:17"

处理复杂的日期时间字符串

Temporal API 没有单一的“万能”解析函数,需要根据输入字符串的格式选择对应的解析方法。

function parseStringDate(s) {
  const parsers = [
    // 情况1:字符串包含完整时区信息(如 [Asia/Shanghai])
    () => Temporal.ZonedDateTime.from(s),
    // 情况2:字符串包含偏移量但无时区名(如 +08:00)
    () => Temporal.Instant.from(s).toZonedDateTimeISO(s),
    // 情况3:纯日期时间字符串(无时区)
    () => Temporal.PlainDateTime.from(s).toZonedDateTime(Temporal.Now.timeZoneId())
  ]

  for (const parser of parsers) {
    try {
      return parser()
    } catch {
      continue
    }
  }
  return null
}

// 使用示例
parseStringDate("2025-02-03T12:31+08:00") // 带偏移量
parseStringDate("2025-02-03T12:31")       // 纯日期时间
parseStringDate("2025-02-03")             // 纯日期

随着 Chrome 的正式支持,Temporal API 为前端开发者提供了一套强大、精确且符合现代工程实践的日期时间处理工具链,有望彻底解决以往在日期计算、时区转换和多日历支持上的诸多痛点。




上一篇:Minio AGPLv3替代方案:5个开源分布式文件系统技术选型指南
下一篇:AirPods安卓功能全解锁:LibrePods开源项目实现降噪与入耳检测(免Root条件)
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2025-12-24 19:21 , Processed in 0.288665 second(s), 40 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2025 云栈社区.

快速回复 返回顶部 返回列表