I4.05.3DST skipped and repeated hours设计
夏令时切换会产生不存在或重复的时刻
别名: 夏令时空洞 · 重复的凌晨两点 · spring forward · fall back
概念解释
春天把钟向前拨,墙上会跳过一截本地时刻,那一截里的「两点半」在当年根本没有;秋天把钟拨回去,同一截本地时刻会走两遍,两点半会来两次。夏令时切换产生不存在或重复的时刻,说的是钟面在这一夜不再是一条光滑的尺子,人按日常钟面去约、去定闹钟、去理解「发生在两点」时会对不上。怎么把这一夜存进数据库,是另一件事;这里只谈这种空洞和重叠怎样把人搞糊涂。
机制
人把本地钟面当成连续、单调、每天都有 24 个整点。夏令时在特定夜里插入一次非连续:跳过则有的钟点从未出现,重复则同一个钟点对应两个不同的瞬间,通常还要靠「第一次 / 第二次」或一个偏移才能分开。闹钟、日历格子、值班表、通宵活动,都是按钟面而不是按瞬间在走。于是出现两类典型困惑:定在空洞里的事,系统可能静默前移、静默取消、或报一个看起来像输入错误的失败;定在重叠里的事,人以为说清了两点半,双方各自落到前后两个瞬间上。
困惑会被「每年是否实行、哪一天实行」放大。同一城市今年改不改夏令时,是政治决定,不是物理定律。人带着去年的记忆来约今年的凌晨,钟面规则已经换了,空洞的位置也会换。
边界
不实行夏令时的时区没有这一夜,把空洞检查做成全球必填会在这些时区制造假警报。相对时间(三小时前)不踩钟面格子,不受空洞直接影响。已经用明确瞬间沟通、双方都看着带偏移的完整时刻时,钟面空洞仍可能出现在「请填本地时间」的输入框里——输入侧仍要面对不存在的钟点。跨过两个时区的人,可能一边有这一夜、一边没有,对照显示会在同一天给出不同长度的本地日,看起来像算错,其实是两边尺子不同。
怎么落地
- 在本地时刻的输入和展示上,遇到空洞:明确告诉人这个钟点今年不存在,并给出最近的合法时刻,不要静默改掉。
- 遇到重叠:让人选择是重叠前还是重叠后的那一次,或改用带偏移的完整时刻,不要只收「02:30」。
- 通宵日程、闹钟、值班在切换日前给出预告,说明这一夜会短一小时或长一小时。
- 验证:在实行夏令时的时区,把闹钟或会议定进春天被跳过的那半小时,界面应拒绝或讲清被移到何处,而不是事后才发现没响。把事件定进秋天重复的两点半,应能区分是第一次还是第二次。在不实行夏令时的时区,同样操作不应冒出空洞警告。