← 中文资源

简体中文版本

Dayjs 时区安全的时间转换

用 Dayjs 的 utc 与 timezone 插件在时区间安全换算时间戳:挂钟时间语义不变,本地时间可反推 UTC 时刻。

阅读英文原文

示例说明

跨时区系统最常见的 bug 是把本地时间字符串当 UTC 解析,或无视夏令时直接加减固定偏移。Dayjs 装载 utc 与 timezone 插件后,同一时刻可以在任意时区投影出正确的挂钟时间;dayjs.tz 则把某时区的挂钟时间锚定为唯一的 UTC 时刻,往返转换不会漂移。

技术要点

  • tz 方法把同一时刻投影到目标时区挂钟
  • dayjs.tz 把本地挂钟时间锚定为 UTC 时刻
  • 夏令时切换日的歧义时间会被规范化

代码解读

raw 是带 Z 后缀的标准 UTC 时刻,三个 tz 调用分别投影出东京、柏林、纽约的本地挂钟字符串,同一数据源零歧义。localMeeting 用上海时区解析 15:00,再 utc() 取回标准时刻。最后演示夏令时切换日的 02:30 这类不存在或歧义的本地时间,Dayjs 会按规则规范化处理而不抛异常。

使用建议

存储与传输一律使用带时区标记的 ISO 字符串,仅在展示层做时区转换。dayjs 的时区数据依赖运行环境的 Intl 能力,老环境需补充 polyfill。定时任务跨夏令时切换期要复核触发时刻。

代码示例

import dayjs from 'dayjs';
import utc from 'dayjs/plugin/utc';
import timezone from 'dayjs/plugin/timezone';

dayjs.extend(utc);
dayjs.extend(timezone);

const raw = '2026-10-22T09:30:00Z';

const tokyo = dayjs(raw).tz('Asia/Tokyo');
const berlin = dayjs(raw).tz('Europe/Berlin');
const ny = dayjs(raw).tz('America/New_York');

console.log('tokyo wall clock:', tokyo.format('YYYY-MM-DD HH:mm'));
console.log('berlin wall clock:', berlin.format('YYYY-MM-DD HH:mm'));

const localMeeting = dayjs.tz('2026-10-22 15:00', 'Asia/Shanghai');
const utcInstant = localMeeting.utc();
console.log('utc instant:', utcInstant.toISOString());

const deadline = dayjs.tz('2026-03-08 02:30', 'America/New_York');
console.log('ambiguous local time normalized to:', deadline.format());