Temporal 明确忽略闰秒,所有对象基于平滑线性的TAI/UTC偏移模型;Instant以纳秒计时、不接受60秒字面量,相减结果恒精确;跨时区展示用ZonedDateTime,但计算须统一用Instant避免日历语义陷阱。

Temporal 提案根本不处理闰秒——它明确选择忽略闰秒,所有 Temporal 对象(包括 Temporal.Instant)都基于平滑、线性的 TAI/UTC 偏移模型,不插入 23:59:60 这类时刻。 这不是缺陷,而是设计取舍:用可预测性换掉闰秒带来的分布式系统雪崩风险。真正需要“跨闰秒”精度的场景(如天文台授时、原子钟同步),JavaScript 本就不该是主力工具链。
为什么 Temporal.Instant 看似能表示“任何时间点”,却对闰秒无感
因为 Temporal.Instant 的底层是 nanoseconds-since-epoch(自 Unix 纪元起的纳秒数),这个值直接映射到国际原子时(TAI)尺度,再通过固定偏移(而非动态跳变)转为 UTC。IERS 公布的闰秒补丁(如 +1s)在 Temporal 中被吸收进时区数据更新(Intl.DateTimeFormat 或 Temporal.ZonedDateTime 的时区规则),而不是修改时间轴本身。
这意味着:
-
Temporal.Instant.from("2016-12-31T23:59:60Z")会抛出RangeError:该字符串不符合 ISO 8601 扩展格式,Temporal 不接受含 60 秒的时间字面量 - 两个
Instant相减得到的Duration永远是精确的纳秒差,不会因闰秒“多算一秒”或“少算一秒” -
Temporal.Now.instant()返回值永远落在标准 UTC 时间线上,比如 2016-12-31T23:59:59.999Z 之后就是 2017-01-01T00:00:00.000Z,中间没有“60 秒”插槽
跨时区计算该用 Temporal.ZonedDateTime,但得避开“本地化陷阱”
当你需要显示“纽约用户看到的是几点”,必须用 ZonedDateTime;但若你在其中做加减运算,就容易误入歧途——因为它的 .add() 或 .subtract() 默认按日历语义(如“加一天”可能跨越夏令时切换点),而非恒定毫秒。
正确做法是分层处理:
- 业务逻辑层:统一用
Temporal.Instant存储、比较、计算间隔(例如订单超时判定、缓存过期检查) - 展示层:仅在最后一步用
zdt = instant.toZonedDateTimeISO({timeZone: "America/New_York"})转成带时区的视图 - 避免写
zdt.add({hours: 24})来推算“明天同一时间”,改用instant.add({days: 1}).toZonedDateTimeISO(...)
否则,当夏令时开始(如 2026-03-09 凌晨 2 点跳到 3 点),zdt.add({days: 1}) 可能返回一个比预期早一小时的 Instant,导致定时任务错位。
如果真要模拟闰秒行为,只能靠外部数据+手动补偿
Temporal 本身不提供闰秒表,但你可以结合 IERS 官方发布的闰秒公告(JSON 格式,含生效时间戳和方向)做轻量补偿:
const leapSeconds = [
{ utc: "2016-12-31T23:59:59Z", delta: +1 },
{ utc: "2017-01-01T00:00:00Z", delta: -1 } // 假设未来出现负闰秒
];
// 使用前先查表,对 Instant 做偏移校正(仅限特殊领域)
function adjustForLeap(instant) {
const ts = instant.epochNanoseconds;
const leap = leapSeconds.find(l => l.utc === instant.toString().split(".")[0] + "Z");
return leap ? instant.add({nanoseconds: leap.delta * 1e9}) : instant;
}但注意:adjustForLeap 是危险操作——它破坏了 Instant 的不可变契约,且无法保证跨服务一致性。除非你控制全链路时间源(如自建 NTP 服务器并打补丁),否则不如承认“JavaScript 不处理闰秒”,把问题边界划清。
真正容易被忽略的点是:很多开发者以为 Temporal 的“现代化”意味着它更“贴近物理现实”,其实恰恰相反——它用数学上的干净时间线,主动切断了与地球自转抖动的耦合。这种割裂不是疏忽,而是让分布式系统敢放心用时间做决策的前提。

















