夏令时变更对UTC转换的影响

9
基本上,我正在将存储在数据库中的本地日期转换为UTC。但是我在某个地方读到,夏令时规则已经在2007年发生了变化。那么Date.ToUniversalTime()函数仍然能够正确地工作吗?基本上,在2007年之前(新规则生效之前)的日期将被正确转换,但之后的日期则不会。我说得对吗?或者 .Net 会在内部处理转换,即根据不同的夏令时规则进行转换?编辑:日期以本地时间存储在数据库中。我正在将其转换为UTC。因此,例如“2005年3月9日”这样的日期应该使用2005年的夏令时规则进行转换,而不是今天的规则。美国在2007年改变了规则。因此,日期会错误地相差一小时。
4个回答

3

这将取决于您使用的.NET版本,可能还取决于您使用的Windows版本。.NET 3.5具有TimeZoneInfo类,其中包括历史更改等内容-在此之前,支持非常不完善。


1
这怎么可能工作?TimeZoneInfo需要知道值何时被添加到数据库中,才能知道应该应用哪些规则。 - Isak Savo
Windows最近开始支持一个丰富的时区模型(包括历史变化)-可能是从2K3或甚至Vista开始,然后服务包应用于旧操作系统。.NET支持以前遵循旧模型(一个规则集,永久适用)。TimeZoneInfo遵循新模型。 - Jon Skeet
是的,但假设我有这个日期在数据库中:“2005-03-10 03:30”(表示为“本地时间”),如何使用 TimeZoneInfo 将此日期转换为 UTC 时间,而不知道保存它所使用的 DST 规则? - Isak Savo
1
@Isak:它不需要知道值何时添加到数据库中。只有当值本身很旧时才需要,而且由于这就是值的本质,所以不应该有问题。 - Joel Coehoorn
@jon:我觉得你没有理解我的意思。有没有保证任何给定的数据库行中的值与添加时间相同。我的意思是,值“2005-03-10…”可能是昨天使用昨天的规则插入到数据库中的,我并不知道 :) - Isak Savo
显示剩余5条评论

1

我会期望ToUniversalTime()会考虑到这一点。你试过并检查了DST变化前后的日期结果吗?

编辑

如果你知道数据库中所有日期的时区偏移量,我强烈建议你在表级别将它们转换为UTC。这样可以摆脱很多麻烦。将其转换为本地时间以供显示目的更容易。


是的,2007年之前的日期在两个月内会出现错误,因为.Net遵循今天的夏令时规则。 - Malik Daud Ahmad Khokhar

1

这取决于数据库中信息的存储方式。

希望数据库中的数据包含UTC偏移量,如果是这样,那么任何夏令时规则的更改都将不相关。

如果未知UTC偏移,则几乎不可能知道如何将其转换为UTC。例如,如果时间以无元数据的整数形式存储,则系统必须知道将其添加到数据库的时间,才能确定对应的UTC时间戳。


时间以本地时间存储在数据库中。需要按照当时的夏令时规则转换为UTC时间。 - Malik Daud Ahmad Khokhar
夏令时规则的更改并不是无关紧要的 - 如果您正在将时间转换为本地时间以进行显示,并且您正在显示旧日期/时间,则它们将是错误的 :( - Jon Skeet
@Jon:啊,你的意思是回答这个问题:“这个日期是否在夏令时期间?”?如果是的话,规则当然是相关的。但对于转换为UTC来说并不适用(因为数据库中的实际日期时间包含了真实偏移量)。 - Isak Savo
夏令时可能是他们曾经提出的前十大最糟糕的想法之一。我想不出这个概念解决的任何问题,但它却创造了许多问题。 - Tomalak
@Dave:你当然是完全正确的。:) 尽管在我居住的寒冷北方,你失去的早晨时间是大多数人睡觉的时间(大约凌晨3点),所以实际上这是额外的一小时阳光。 - Isak Savo
显示剩余4条评论

1

我很不想这么说,但你已经陷入了困境。在问题变得更糟之前,咬紧牙关并将数据库中的日期更改为UTC时间。如果你继续尝试在数据库中存储本地时间,你的代码很快就会成为特殊情况日期计算的噩梦。

妥协方案:在不同的列中存储本地时间和UTC时间;至少那样你会有一个参考点

请参阅this post了解更多永远不要将db时钟存储在本地时间的原因


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接