在XP和Windows 7上执行以下操作会在.NET4与.NET2控制台应用程序中产生不同的结果:
Console.WriteLine(String.Format("DateTime.Parse on Client: {0}",
DateTime.Parse("1998-10-31T00:00:00-04:00")));
.NET4
在XP下,返回: 10/31/1998 12:00:00 AM
在Windows 7 / Windows 8下,返回: 10/30/1998 11:00:00 PM
.NET2
在XP下,返回: 10/31/1998 12:00:00 AM
在Windows 7 / Windows 8下,返回: 10/31/1998 12:00:00 AM
WHY ??!?
从字符串中删除TimeZone(-04:00)会导致.NET4下的XP和Windows 7上的值相同。当从字符串执行DateTime.Parse时,Windows XP似乎在.NET4下以不同的方式应用时区偏移量。有没有办法改变这种行为,以便它在.NET4下是一致的,无论操作系统如何(不涉及操纵发送到DateTime.Parse的字符串)
环境: 所有计算机都安装了最新的修补程序(可通过Windows Update获得),并配置为“东部时间”,并在“时区设置”中选中“自动调整夏令时的时钟”。
我已在使用.NET4的Windows 7计算机和使用.NET4.5的Windows 7计算机上确认此行为
答案 0 :(得分:5)
计算历史日期的本地时间要求.NET了解在该日期生效的夏令时规则。这当然是一件相当棘手的事情,因为DST规则在不同地区和日期之间变化很大。
您的日期的UTC偏移为-4,这使其位于美国东部时区附近。最相关的夏令时规则改变了2005年能源政策法案,该法案将DST从3月的第2个星期日到11月的第1个星期日生效,从2007年开始生效。因此了解当地时间1998年10月31日要求知道这项法律尚未生效。
这就是差异的来源。 Windows Vista是第一个拥有这些DST更改数据库的Windows版本,.NET 4是第一个开始使用它的.NET版本。 XP没有该数据库,因此.NET不能做任何事情,只是假设当前的DST规则有效。
这是在与当地时间合作时需要处理的不可避免的损失。不要,使用UTC。
答案 1 :(得分:1)
DateTime
值不能表示任意偏移量。它只跟踪.Kind
属性,可以是UTC
,Local
或Unspecified
。
当你将一个字符串解析为1>}而没有的偏移量时,该类型将为DateTime
。
当您将带有偏移量的字符串解析为Unspecified
时,该类型将为DateTime
,然后根据您提供的偏移量调整时间和从当地时区确定的偏移量。
因此Local
首先转换为UTC 1998-10-31T00:00:00-04:00
,然后应用本地计算机的偏移量(在您的情况下,东部夏令时间-05:00),您将获得{{1}的本地时间}}
汉斯在答案中解释说,.Net 2.0和Windows XP都无法正确区分同一时区内的夏令时差异。所以你总是会回到东方时间-04:00,无论是哪个日期。
避免所有这些废话的最佳方法是使用1998-10-30T20:00:00-00:00
类型。它将跟踪您最初给出的偏移量,并且您可以在必要时进行转换。它存在于带有SP1的.Net 2.0中,但在.Net 3.5+(包括4.0)下,您还可以使用1998-10-30T23:00:00-05:00
类来轻松操作它。
因此,请将您的代码更改为DateTimeOffset
,您的状态会更好。
答案 2 :(得分:0)
听起来好像一台机器在其环境设置中检查了夏令时,而另一台则没有。