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

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

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

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

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

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

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

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

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


当前回答

永远不要只依赖像这样的构造函数

 new DateTime(int year, int month, int day, int hour, int minute, TimeZone timezone)

当某个日期时间由于DST而不存在时,它们可以抛出异常。相反,构建自己的方法来创建这样的日期。在它们中,捕捉由于DST而发生的任何异常,并使用转换偏移调整所需的时间。根据时区,夏令时可能会在不同的日期和时间(甚至巴西的午夜)发生。

其他回答

如果您的设计能够适应,请避免同时转换本地时间!

我知道对一些人来说,这可能听起来很疯狂,但想想用户体验:用户处理接近的相对日期(今天、昨天、下周一)比绝对日期(2010.09.17,星期五-9月17日)的速度要快。当你仔细考虑时,时区(和DST)的准确度越接近现在()就越重要,所以如果你可以用+/-1或2周的相对格式表示日期/日期时间,其余的日期可以是UTC,这对95%的用户来说并不重要。

通过这种方式,您可以以UTC存储所有日期,并以UTC进行相对比较,只需向用户显示超出相对日期阈值的UTC日期。

这也适用于用户输入(但通常以更有限的方式)。从只有{昨天、今天、明天、下周一、下周四}的下拉列表中进行选择,对于用户来说,比日期选择器更简单、更容易。日期选择器是表单填充中最令人痛苦的部分。当然,这并不适用于所有情况,但您可以看到,它只需要一点巧妙的设计就可以使其非常强大。

通常,在存储的时间戳中包含本地时间偏移量(包括DST偏移量):如果您以后想在原始时区(和DST设置)中显示时间戳,仅使用UTC是不够的。

请记住,偏移量并不总是整数小时(例如,印度标准时间为UTC+05:30)。

例如,合适的格式是元组(unix时间,以分钟为单位的偏移量)或ISO 8601。

永远不要只依赖像这样的构造函数

 new DateTime(int year, int month, int day, int hour, int minute, TimeZone timezone)

当某个日期时间由于DST而不存在时,它们可以抛出异常。相反,构建自己的方法来创建这样的日期。在它们中,捕捉由于DST而发生的任何异常,并使用转换偏移调整所需的时间。根据时区,夏令时可能会在不同的日期和时间(甚至巴西的午夜)发生。

我只想指出两件似乎不准确或至少令人困惑的事情:

始终按照统一的标准坚持时间,而不是受夏令时影响。GMT和UTC已被不同的人,尽管UTC似乎最常被提及。

对于(几乎)所有实际的计算目的来说,UTC实际上是GMT。除非你看到一个分数秒的时间戳,否则你要处理的是GMT,这使得这种区分变得多余。

在以下情况下按原样包括本地时间偏移(包括DST偏移):存储时间戳。

时间戳始终以GMT表示,因此没有偏移量。

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


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