TimeZoneInfo.ConvertTimeFromUtc returns incorrect result

不羁的心 提交于 2021-01-27 13:57:16

问题


I have a very strange behaviour with TimeZoneInfo.ConvertTimeFromUtc. How do you think what this returns?

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

Belarus Standard Time is UTC+3. And I expect {01.01.2000 15:00:00}. But I see the next:

WAT?

This worked correctly some days ago. But today I have run unit tests and noticed this. Before running the tests I installed Visual Studio 2015. What could happen and why? How to fix it?

PS: It works correctly on another machine.


回答1:


Actually, the conversion is correct.

While it's true that Belarus currently has a time zone that is UTC+3 all year, it has only been that way since 2012.

Prior to that, its standard offset was UTC+2, and it observed a daylight time (aka "summer time") offset of UTC+3 from the last Sunday in March through the last Sunday in October. This change was enacted by remaining on summer time in 2011 and staying there permanently, rather than falling back.

You can see the history of changes here.

When you use the "Belarus Standard Time" time zone, the information for this zone is pulled from the data in the Windows registry at the following location:

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

There you will see the basic information, and a subkey called Dynamic DST that contains the year-over-year changes. You'll notice that Windows has three entries for this zone:

  • One for 2010 and prior, which alternates between standard time and daylight time
  • One for 2011 which makes the single change to daylight time without returning to standard time
  • One for 2012 and greater, which is fixed at standard time with the new base offset

Note that this is a simplification of the full IANA TZDB entry of "Europe/Minsk", which tracks other changes in 1992 and prior. Windows doesn't know about those changes, so if you are going to be working with historical dates with this time zone, you should consider using Noda Time instead of TimeZoneInfo, as Noda Time has support for the TZDB time zones.

Also, note that since the data is modeled in Windows as 2011 and prior having a different base offset than the 2012 and forward rule, then it is impacted by the issue described in KB2012229. The status section of that article is outdated, as the issue was resolved with .NET 4.6. Even if you are targeting .NET 3.5 through .NET 4.5.2, if .NET 4.6 is installed on the machine at all, then it will behave correctly. If .NET 4.6 is not installed on the machine, it will apply the wrong base offset for Belarus to years 2011, 2010, and prior. (This is why SonerGönül got the time of 15:00 mentioned in the question comments.)



来源:https://stackoverflow.com/questions/33545021/timezoneinfo-converttimefromutc-returns-incorrect-result

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!