TimeZoneInfo.ConvertTimeFromUtc返回不正确的结果

时间:2015-11-05 12:50:34

标签: c# datetime timezone

我对TimeZoneInfo.ConvertTimeFromUtc有一种非常奇怪的行为。 你怎么看待这回归?

var date = new DateTime(2000, 1, 1, 12, 0, 0);
var dest = TimeZoneInfo.FindSystemTimeZoneById("Belarus Standard Time");
TimeZoneInfo.ConvertTimeFromUtc(date, dest);

白俄罗斯标准时间为UTC + 3。我希望{01.01.2000 15:00:00}。 但我看到了下一个: enter image description here

WAT?

这几天前工作正常。但今天我已经进行了单元测试并发现了这一点。在运行测试之前,我安装了Visual Studio 2015.可能会发生什么?为什么?如何解决?

PS:它可以在另一台机器上正常工作。

1 个答案:

答案 0 :(得分:2)

实际上,转换是正确的。

虽然白俄罗斯目前的时区全年为UTC + 3,但自2012年以来只有这样。

在此之前,其标准偏移量为UTC + 2,并且它观察到从3月的最后一个星期日到最后一个星期日的UTC + 3的白天时间(又名“夏令时”)偏移在十月。这一变化是在2011年夏季时间留下并永久停留在那里,而不是退回。

You can see the history of changes here

当您使用"Belarus Standard Time"时区时,此区域的信息将从以下位置的Windows注册表中的数据中提取:

HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\Belarus Standard Time

在那里,您将看到基本信息,以及一个名为Dynamic DST的子项,其中包含年度变化。您会注意到Windows有三个条目用于此区域:

  • 2010年及之前的一个,在标准时间和白天时间之间交替
  • 2011年的一次,只需更改为白天时间而不返回标准时间
  • 一个用于2012及更高版本,使用新的基本偏移量固定在标准时间

请注意,这是full IANA TZDB entry of "Europe/Minsk"的简化,它跟踪1992年及之前的其他变化。 Windows不知道这些更改,因此如果您要使用此时区处理历史日期,则应考虑使用Noda Time而不是TimeZoneInfo,因为Noda Time支持TZDB时区。

另请注意,由于数据在Windows中建模为2011年,并且之前的基本偏移量与2012年和转发规则不同,因此受KB2012229中描述的问题影响。该文章的状态部分已过时,因为该问题已通过.NET 4.6解决。即使您的目标是.NET 3.5到.NET 4.5.2,如果计算机上安装了.NET 4.6,那么它的行为也会正确。如果计算机上未安装.NET 4.6,则会将白俄罗斯的错误基准偏移量应用于2011年,2010年及之前的年份。 (这就是SonerGönül在问题评论中提到15:00时间的原因。)