前阵子同事排查一个定时任务,现象特别诡异:每天凌晨的批处理,有那么几天会整点往后挪一小时,日志看起来毫无规律。最后定位到根因,是夏令时切换那天,任务调度器用的"本地时间"在切换窗口里被悄悄改了读数。
嗯
这类坑的本质,是把 wall clock 当成了可排序、可相减的物理量。其实本地时间根本不是单调的:夏令时开始时凌晨两点直接跳到三点,那天少了一小时;结束时三点回退到两点,同一个时刻会出现两次。你要是拿本地时间当时间戳存库,跨时区或者跨夏令时边界一做排序、一算差值,结果全乱。
还有人想当然觉得 UTC+8 永远固定。中国确实不实行夏令时,但很多基础设施、上游服务、甚至你调的第三方 API 是在实行夏令时的地区跑的。你以为锁死 +8 就稳了,结果对方那边一切换,你的定时任务就跟着偏。
根治办法其实朴素:存储层统一用带时区信息的 UTC(或者干脆 epoch 秒),只在展示层按用户所在时区做转换。什么时候该转、往哪转,逻辑集中在一处,别让"本地时间"散落到业务代码各个角落。