在XP和Windows7上执行以下操作会在.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
为什么??!?
从字符串中删除TimeZone ( -04:00)将导致.NET4下XP和Windows 7上的值相同。当从字符串执行.NET4时,Windows似乎以不同的方式应用DateTime.Parse下的时区偏移量。是否有办法改变这种行为,使其在.NET4下是一致的,没有规则的操作系统(不涉及操纵被发送到DateTime.Parse的字符串)?
环境:所有机器都安装了最新的修补程序(可通过Windows获得),并配置为东方时间,并在“时区设置”中签入“自动调整夏令时时钟”。
我已经在带有.NET4的Windows 7机器和带有.NET4.5的Windows 7机器上确认了这种行为
发布于 2013-01-10 16:33:22
计算历史日期的本地时间需要.NET知道在该日期期间有效的夏令时规则。当然,这是一件非常棘手的事情,因为DST规则在不同的地区和日期有很大的差异。
您的日期有一个UTC偏移-4,这使它靠近美国东部时区。2005年“能源政策法案”将DST的有效期从3月的第二个星期日延长到11月的第一个星期日,并于2007年生效。因此,要知道1998年10月31日的当地时间,就必须知道这项法律尚未生效。
这就是区别的来源。Windows是第一个拥有这些DST更改数据库的Windows版本,.NET 4是第一个开始使用它的.NET版本。XP没有那个数据库,所以.NET只能假设当前的DST规则是有效的。
这是您在处理本地时间时需要处理的不可避免的损失。不要用UTC。
发布于 2013-01-21 18:59:41
DateTime值不能表示任意偏移量。它只跟踪.Kind属性,可以是UTC、Local或Unspecified。
当您将没有偏移量的字符串解析为DateTime时,这类字符串将是Unspecified。
当将带有偏移量的字符串解析为DateTime时,类型为Local,然后根据所提供的偏移量和从本地时区确定的偏移量调整时间。
因此,首先将1998-10-31T00:00:00-04:00转换为UTC 1998-10-30T20:00:00-00:00,然后应用本地计算机的偏移量(在您的例子中,东部夏令时间-05:00),您将得到1998-10-30T23:00:00-05:00的本地时间。
正如汉斯在回答中所解释的,无论是Windows2.0还是Windows,都无法正确区分同一时区内的夏时制差异。所以无论是哪一天,你都会回到东部-04:00。
避免所有这些无稽之谈的最好方法是使用DateTimeOffset类型。它将跟踪您最初给它的偏移量,您可以在必要时转换它。它存在于.Net 2.0和SP1中,但是在.Net 3.5+ (包括4.0)下,您也可以使用TimeZoneInfo类轻松地操作它。
因此,将您的代码更改为DateTimeOffset.Parse("1998-10-31T00:00:00-04:00"),您将处于更好的状态。
发布于 2013-01-10 01:32:53
这听起来像是一台机器在其环境设置中检查了夏时制,而另一台则没有。
https://stackoverflow.com/questions/14249331
复制相似问题