夏令时转换的两个坑:不存在的时间与歧义时间
夏令时让一年里有两天不是 24 小时:开始那天少一小时,结束那天多一小时。于是「把日期转成时间戳」在这两天会出现两类特殊情况——被跳过的时间根本不存在,被回拨的时间有两个对应时刻。处理错了不会报错,只会安静地差一小时。
不存在的时间:凌晨 2:30 去哪了
以纽约为例,2026 年 3 月 8 日凌晨 2:00 直接跳到 3:00。也就是说 2026-03-08 02:30 这一刻从来没有发生过。
如果把它当普通时间转成时间戳,多数语言会「帮你」顺延到 3:30,或者回退到 1:30——两种结果都不可预期,而且不同语言不一致。这类值出现在定时任务、预约系统里,就会表现为「任务没执行」或「提前执行了」。
这个工具遇到不存在的时间会明确提示原因,而不是给出一个看起来正常的错误结果。
歧义时间:凌晨 1:30 出现两次
同年 11 月 1 日,纽约从 2:00 回拨到 1:00,于是 01:00–02:00 这一小时出现了两次。写 2026-11-01 01:30,它对应两个不同的绝对时刻,相差一小时。
处理这类值的通行做法是取较早的一次(第一次出现),并在界面与日志里标注存在歧义。这个工具会说明有两个对应时刻并取较早一次,不会假装它没有歧义。
为什么不能自己加减一小时
夏令时不是全球统一,也不是每年固定日期:美国是三月第二个周日、欧洲是三月最后一个周日,南半球相反,中国、日本、印度根本不实行。用「三月就加一小时」的规则去算,一年里至少错两次,而且错在不同国家。
正确做法只有一条:用带完整历史规则的时区数据库(IANA tz database)。浏览器的 Intl API 就带着这份库,包括各国历年的规则变更——比如某国某年临时取消了夏令时,库里有记录。
存储用 UTC,展示用本地
工程上避开这两类坑的通用做法:存时间戳或带时区的 ISO 字符串,展示时再按用户时区格式化。这样「不存在的时间」永远进不了数据库——因为它压根不是某个绝对时刻。
只有在用户输入了一个日期时间(比如预约明天上午 9 点)时,才需要处理这两类边界,而且要当场告诉用户「这个时间不存在」。等存进库里再发现就晚了。
上面这些都不用装软件,也不用注册:打开页面就能用。
打开时间戳转换 →常见问题
中国有夏令时吗?
现在没有。中国在 1986–1991 年实行过夏令时,之后取消。所以在中国大陆做时间转换一般不会遇到这两类问题,但服务海外用户或处理历史数据时仍要处理。
夏令时会让时间戳重复或跳过吗?
不会。时间戳是单调递增的绝对秒数,夏令时只影响「时刻 → 本地日期时间」的映射。跳过和重复只发生在本地时间的表示上。
怎么判断某个时间戳是否落在夏令时期间?
看该时区在那个时刻的 UTC 偏移是否为夏令时偏移。用 Intl 的 timeZoneName 长格式可以拿到「GMT+8」这类信息,再与该时区的标准偏移比较。