我正在使用DateTime.ToLocalTime()
将日期从UTC转换为本地时间。我的时区是GMT + 1(贝尔格莱德,布达佩斯,Lubjna ...),它在Windows设置(XP)中正确设置。
上个周末在我们的时区我们改为冬季到夏季,这意味着,我们将当地时间缩短了一个小时。
当我看到ToLocalTime方法从那一刻起表现得很奇怪。当我用它来转换这个冬天时间变化之后的日期时,效果很好,就像这样:
var utcDate2 = new DateTime(2011, 11, 2, 9, 0, 0,DateTimeKind.Utc);
utcDate1.ToLocalTime()
值为:2011.11.02. 10:00:00
它是正确的
如果我想在此更改之前转换日期(例如夏令时的日期),那么它会给出一个错误的值,如下所示:
var utcDate1 = new DateTime(2011, 10, 23, 9, 0, 0,DateTimeKind.Utc);
utcDate2.ToLocalTime()
值为:2011.10.23. 10:00:00
它不正确它应该是2011.10.23。 11:00:00
我应该怎样做才能获得正确的价值?我应该如何使用ToLocalTime来调整冬季/夏季时间?
答案 0 :(得分:6)
http://msdn.microsoft.com/en-us/library/system.datetime.tolocaltime.aspx
在Windows XP系统上,ToLocalTime方法仅识别 从UTC转换为本地时的当前调整规则。作为一个 结果,转换当前调整规则之前的句点 生效可能无法准确反映UTC之间的差异 和当地时间。
所以你必须找到另一种解决方法。
答案 1 :(得分:1)
我的猜测是系统上的时区数据可能过时 - 或者是由于jsobo提到的限制。
您可能想要(谨慎)追求的一个选项是使用我的日期/时间API,Noda Time。这可以转换为DateTime
,因此您可以在代码中的其他位置使用DateTime
,但显然我相信如果您在整个过程中使用Noda Time,您的代码会更清晰:)< / p>
Noda Time还没有“v1.0-ready”,但主要是因为缺少一些功能。当然,您是否愿意承担非v1.0开源项目的风险取决于您,但我很乐意帮助解决您遇到的任何问题。 (我真的想找到真实的用例,所以如果你需要任何缺失的功能,我很可能能够实现它们,以期其他人需要相同的东西。)
Noda Time使用zoneinfo时区数据库,而不是Windows内置的数据库,因此它不应该有相同的问题。
要检查,您可以使用以下代码:
DateTimeZone belgradeZone = DateTimeZone.ForId("Europe/Belgrade"); // Or whatever
// Alternatively...
DateTimeZone localZone = DateTimeZone.SystemDefault;
ZonedDateTime utc = new ZonedDateTime(2011, 10, 23, 9, 0, 0, DateTimeZone.Utc);
ZonedDateTime belgrade = new ZonedDateTime(utc.ToInstant(), belgradeZone);
Console.WriteLine(belgrade.LocalDateTime);
答案 2 :(得分:1)
我使用相同的时区,当我尝试时,我得到正确的值:
var utcDate1 = new DateTime(2011, 10, 23, 9, 0, 0, DateTimeKind.Utc);
Console.WriteLine(utcDate1);
Console.WriteLine(utcDate1.ToLocalTime());
var utcDate2 = new DateTime(2011, 11, 2, 9, 0, 0, DateTimeKind.Utc);
Console.WriteLine(utcDate2);
Console.WriteLine(utcDate2.ToLocalTime());
输出:
2011-10-23 09:00:00
2011-10-23 11:00:00
2011-11-02 09:00:00
2011-11-02 10:00:00
答案 3 :(得分:0)
.NET在幕后进行一些计算。我建议您阅读Raymond Chen关于隐式时区转换的this article。