不列颠哥伦比亚、时区,以及 Postgres
存储时间戳:UTC 还是本地时间
- 对“始终存 UTC”存在强烈分歧。
- 一派认为:只存 UTC Unix 时间戳作为事实来源;通过可信库进行转换;时区过于复杂,不能手工处理。
- 另一些人认为,当关心的是墙上时钟时间(预约、打卡、办公时间)时,这是一种“常见错误”。本地时间独立于 UTC 存在,通常应该直接存储。
- 还有人强调,UTC 适用于字面上的瞬时点(日志、已经发生的事件),而不适用于与本地时钟绑定的领域概念。
未来事件与时区变化(BC 案例)
- 核心问题:一个设定为“本地时间下午 2 点”的未来预约,如果法律发生变化(例如不列颠哥伦比亚改为永久夏令时),可能会映射到不同的 UTC 时刻。
- 这迫使人们在“权威”参考之间做选择:
- 事件地点的本地墙上时间,或
- 最初计算出的 UTC 时刻,或
- 多时区会议中另一位参与者的本地时间。
- 一些评论者强调,任何对未来事件的表示本质上都是暂定的;政府和边界都可能变化。
模式和建模策略
- 针对未来事件,提出的方案包括:
- 存储本地日期/时间 + IANA 时区(例如
America/Vancouver),可选再加地点。 - 对于预约,使用 DATE/TIME 或不带时区的 TIMESTAMP 表示本地时间;只在展示层进行转换。
- 另外保留一个 UTC 时刻用于查询/优化,但要清楚标明哪个字段是权威来源。
- 存储本地日期/时间 + IANA 时区(例如
- 对于过去事件:很多人建议使用 UTC,只有在本地墙上时间在语义上重要时才保留时区(例如打卡、历史分析)。
- 有人建议存储时区偏移量和/或 tzdata 版本或插入时间,以便在规则或数据变化时重建意图。
库、tzdata 与复杂性
- 共识是:永远不要重写时区逻辑;要依赖基于 tzdata 的库。
- 但 tzdata 本身会频繁变化,既影响过去时间戳,也影响未来时间戳,而且可能包含历史错误。
- 一些想法包括:为每条记录跟踪 tzdata 版本的系统,或使用类似双时态的策略来记录“当时我们相信什么”。
DST、政策与 BC 的反应
- 很多人普遍批评夏令时,更倾向于永久时间,但对永久标准时间还是永久夏令时间哪种更健康意见不一。
- 不列颠哥伦比亚决定采用永久夏令时颇具争议;一些居民喜欢结束改钟,另一些人认为咨询过程有误导性,而且标准时间会更好。