我希望将这个问题及其答案作为处理夏令时的最终指南,特别是处理实际转换时。

如果你有什么要补充的,请做

许多系统都依赖于保持准确的时间,问题是由于夏时制而导致的时间变化——向前或向后移动时钟。

例如,一个订单接受系统中的业务规则取决于订单的时间——如果时钟发生变化,规则可能就不那么清晰了。应如何保持订单的时间?当然,有无数的场景——这只是一个例证。

你是如何处理日光节约问题的?您的解决方案包含哪些假设?(在此处查找上下文)

同样重要,如果不是更重要的话:

你尝试了什么但没有奏效?为什么不起作用?

我会对编程、操作系统、数据持久性和其他相关方面感兴趣。

一般的答案很好,但我也希望看到细节,特别是如果它们只在一个平台上提供的话。


当前回答

跨越“计算机时间”和“人类时间”的界限是一场噩梦。主要原因是,时区和夏令时的规则没有一种标准。各国可以随时自由更改时区和夏令时规则,他们也可以这样做。

一些国家,例如以色列、巴西,每年都会决定何时实行夏令时,因此无法提前知道夏令时何时生效。其他人对DST何时生效有固定的规则。其他国家并不完全使用夏令时。

时区不必与格林尼治标准时间相差整整一小时。尼泊尔为+5.45。甚至还有+13的时区。这意味着:

SUN 23:00 in Howland Island (-12)
MON 11:00 GMT 
TUE 00:00 in Tonga (+13)

都是同一时间,但3天不同!

对于时区的缩写,以及它们在夏令时中的变化,也没有明确的标准,因此您最终会遇到这样的情况:

AST Arab Standard Time     UTC+03
AST Arabian Standard Time  UTC+04
AST Arabic Standard Time   UTC+03

最好的建议是尽可能远离当地时间,尽可能坚持UTC。仅在最后一刻转换为当地时间。

测试时,请确保您测试了西半球和东半球的国家,其中既有正在进行的夏令时,也有未使用夏令时的国家(共6个)。

其他回答

永远不要在没有UTC偏移(或时区参考)的情况下存储本地时间-如何不这样做的示例包括C¹中的FAT32和结构tm了解时区是一组UTC偏移(例如,冬季+0100,夏季+0200)切换发生的时间规则(可能会随着时间的推移而改变:例如,在20世纪90年代,欧盟将切换统一为3月和10月的最后一个星期日,标准时间02:00/夏令时03:00;之前成员国之间有所不同)。


¹struct tm的一些实现确实存储UTC偏移量,但这并未将其纳入标准。

这是一个重要而令人惊讶的棘手问题。事实是,对于坚持时间没有完全令人满意的标准。例如,SQL标准和ISO格式(ISO 8601)显然不够。

从概念角度来看,通常处理两种类型的时间-日期数据,区分它们很方便(上述标准没有):“物理时间”和“民事时间”。

时间的“物理”瞬间是物理学处理的连续宇宙时间线中的一个点(当然忽略了相对论)。例如,如果可以忽略闰秒,则可以在UTC中对这个概念进行适当的编码。

“民用”时间是遵循民用规范的日期时间规范:这里的时间点完全由一组日期时间字段(Y、M、D、H、MM、S、FS)加上TZ(时区规范)(实际上也是“日历”;但假设我们将讨论限于公历)来指定。时区和日历共同允许(原则上)从一个表示映射到另一个表示。但是,民用和物理时间瞬间是本质上不同类型的量值,它们应该在概念上分开并以不同的方式对待(一个类比:字节和字符串的数组)。

这个问题令人困惑,因为我们可以互换地谈论这些类型的事件,并且因为公民时代会受到政治变化的影响。这个问题(以及区分这些概念的必要性)在未来的事件中变得更加明显。示例(摘自我在这里的讨论。

约翰在日历上记录了某个日期的事件提醒2019-Jul-27,10:30:00,TZ=智利/圣地亚哥,(已偏移GMT-4,因此它对应于UTC 2019-Jul-27 14:30:00)。但总有一天未来,该国决定将TZ偏移量改为GMT-5。

现在,当这一天到来。。。该提醒是否应在

A) 2019-Jul-27 10:30:00智利/圣地亚哥=UTC时间2019-Jur-27 15:30:00?

or

B) 2019-Jul-27 9:3:00智利/圣地亚哥=UTC时间2019-Jul-27 14:30:00?

没有正确的答案,除非你知道约翰在概念上的意思当他告诉日历“请在2019年7月27日10:30:00给我打电话TZ=智利/圣地亚哥”。

他是说“公民约会时间”吗10:30“)?在这种情况下,A)是正确答案。

或者他是指“物理上的瞬间”,连续波中的一个点我们宇宙的时间线,比如,“下一次日食在这种情况下,答案B)是正确的。

一些Date/Time API正确地实现了这一区别:其中的Jodatime是下一个(第三个!)Java DateTime API(JSR 310)的基础。

将服务器设置为UTC,并确保所有服务器都配置为ntp或同等版本。

UTC避免了夏令时问题,服务器不同步可能会导致不可预测的结果,需要一段时间才能进行诊断。

明确关注点的架构分离-准确地知道哪个层与用户交互,并且必须更改规范表示(UTC)的日期时间。非UTC日期时间是表示(遵循用户本地时区),UTC时间是模型(对于后端和中间层仍然是唯一的)。

此外,决定你的实际受众是什么,你不需要服务什么,你在哪里划分界限。除非你在那里有重要的客户,否则不要接触异国情调的日历,然后考虑为该地区单独的面向用户的服务器。

若您可以获取并维护用户的位置,则可以使用位置进行系统的日期时间转换(例如.NET区域性或SQL表),但如果日期时间对您的用户至关重要,则为最终用户提供一种选择覆盖的方式。

如果涉及历史审计义务(例如准确地告诉亚利桑那州的Jo在2年前的9月支付账单的时间),则记录UTC和当地时间(您的转换表会随着时间的推移而改变)。

为批量提供的数据(如文件、web服务等)定义时间参考时区。如果东海岸公司在加利福尼亚州设有数据中心,您需要询问并了解他们使用什么作为标准,而不是假设其中之一。

不要相信嵌入在日期时间文本表示中的时区偏移,也不要接受解析和跟踪它们。相反,始终要求明确定义时区和/或参考区域。你可以很容易地用PST偏移量接收时间,但时间实际上是EST,因为这是客户端的参考时间,记录只是在PST中的服务器上导出的。

仅举一个例子来证明,处理时间是描述的巨大混乱,你永远不会自满。在本页的几个地方,闰秒被忽略了。

几年前,Android操作系统使用GPS卫星获取UTC时间参考,但忽略了GPS卫星不使用闰秒的事实。没有人注意到,直到除夕夜出现了混乱,苹果手机用户和安卓手机用户相隔约15秒进行倒计时。

我想它已经被修复了,但你永远不知道这些“小细节”什么时候会回来困扰你。