
这些城市今时今日使用同一个时区,但这不意味着它们历史上一直使用同一个时区。为了兼容历史上曾经存在的不同时区,这些时区代码必须延续下来。
首先我们来看一个 StackOverflow 2011 年的经典问题:
有人问,为什么把 1927-12-31 23:54:07 和 1927-12-31 23:54:08 分别转换为整型时间戳后它们的数值相差 353,而不是相差 1(因为前后距离 1 秒)。这个提问者最初并不是针对这一秒做计算的,而是针对某个 1927 年的区间做计算,发现结果不符合预期然后把问题根源定位到上述这相差 353 秒的 1 秒。
为什么时钟上相差 1 秒的时间实际上会相差 353 秒?一开始没有人知道正确答案,然而有大神冲进去问「你执行这段代码的语言、语言版本是什么?实际执行代码的机器的本地时区是什么?」提问者说这是 Java 6,时区是 Asia/Shanghai,然后真相就出现了。
(1927 年?1928 年?那段时间的历史资料混乱,所以 Java 时区数据库和 Wikipedia 可能用了不同的历史资料反应相同的时区变更。)因为那时候民国对上海时区进行了调整,上海时区往前调整了 5:52,所以时钟上相邻的 1 秒实际间隔 353 秒。以下是 Wikipedia 提供的民国 5 个时区的划分:
你永远也不知道你的时间数据什么时候会用来存储一个久远的时间,你可能也不知道那时候的时区是怎样划分和定义的。你能做的就是尽量选择正确的时区来处理时间数据,把剩下的事情留给时区数据库处理。
这是其它答案里讨论的 tz 开源时间数据库,大家可以看到 Asia/Shanghai 的历史,往下阅读还能看到 Asia/Urumqi 的时区曾经是非整点的 +05:50:20,Asia/Hong_Kong 曾经是 +07:36:42,Asia/Macau 曾经是 +07:34:10,Asia/Taiwan 曾经是 +08:06:00。
这些时区曾经都是按照各个城市正午为 12:00 进行定义的,而整点时区的经度必然是 15° 的整数倍,城市地理中心的经度几乎不可能天然地成为 15° 的整数倍,所以历史上城市之间的时差都不是整点的。
