本文介绍了.NET有时区变化的历史吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述 29岁程序员,3月因学历无情被辞! 我们的政府喜欢改变当地时间或启用|禁用夏令时。Our government loves to change local time or enable|disable daylight saving time. MS部署了俄罗斯的补丁,以考虑新的时间变化。MS deployed patch for Russia to take new time change into account.现在有问题是否存在更改的历史记录?Now there is the question whether history of the changes exists?当我得到UTC的时间在01.01.2000系统应该记住,莫斯科时区有+3 UTC。 (在夏天+4)。When I get UTC time of the day in 01.01.2000 system should remember that Moscow time zone had +3 UTC. (in summer +4) at that moment.对于01.01.2012,冬天和夏天都有+4 UTC。不久之后,我们将有+3 UTC。For 01.01.2012 we had +4 UTC for both winter and summer. And soon we will have +3 UTC.简单测试显示,.NET不会保留有关更改的记录:simple test shows that .NET does not keep records about the changes:var t = new DateTime(2012,1,1);// UTC +4 expectedSystem.Console.WriteLine(t.ToLocalTime());// UTC +4 expectedt = new DateTime(2012,06,1);System.Console.WriteLine(t.ToLocalTime());// UTC +3 expectedt = new DateTime(2000,1,1);System.Console.WriteLine(t.ToLocalTime());// UTC +4 expectedt = new DateTime(2000,6,1);System.Console.WriteLine(t.ToLocalTime());是否存在一些额外的API来应对问题?Does some additional API exist to cope with the problem? 更新:找到了一个类 TimeZoneInfo 及相关的 AdjustmentRule 类。留下来测试是否定制 TimeZoneInfo.Local 时区影响DateTime API。Have found class TimeZoneInfo and related AdjustmentRule class. Left to test whether customization of TimeZoneInfo.Local time zone affects DateTime APIs. 更新2: / strong> 似乎UTC偏移量不会作为历史存储, AdjustmentRule 仅在一年中更改日光时间。Update 2:Seems like UTC offsets are not stored as history and AdjustmentRule changes only daylight time during the year.推荐答案 .NET跟踪某些历史记录,但并不总是准确的。您已经偶然发现了一个不准确之处。.NET tracks some history, but it is not always accurate. You've stumbled upon one of the inaccuracies. .NET通过注册表从Windows导入所有的时区信息,如这里和此处。如果您在注册表中查看 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\Russian Standard Time\Dynamic DST 发现它只跟踪2010年的这个时区的信息。 2000年的测试日期不会很好,因为它将回到最早的规则(2010)。.NET imports all of it's time zone information from Windows via the registry, as described here and here. If you look in the registry at HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones\Russian Standard Time\Dynamic DST you'll find that it only tracks information from 2010 forward for this time zone. Testing dates in year 2000 is not going to work well, as it will fall back to the earliest rule available (2010).基地UTC偏移信息是在.NET中导入的 AdjustmentRule 类中注册表中的不。如果您检查此时区的调整规则,您会发现根本没有导入2012和2013:Base UTC offset information is tracked in the registry, but not in the AdjustmentRule class that .NET imports it into. If you check the adjustment rules for this time zone, you'll find that 2012 and 2013 are not imported at all:var tz = TimeZoneInfo.FindSystemTimeZoneById("Russian Standard Time");foreach (var rule in tz.GetAdjustmentRules()){ Console.WriteLine("{0:d} - {1:d}", rule.DateStart, rule.DateEnd);} OUTPUT:1/1/0001 - 12/31/20101/1/2011 - 12/31/20111/1/2014 - 12/31/2014即使它们存在于Windows注册表中,2012年和2013年由于没有夏令时间调整,因此没有导入。Even though they exist in the Windows registry, 2012 and 2013 are not imported because they have no daylight saving time adjustments.当基本偏移量更改时,会产生问题 - 就像这个时区一样。由于目前为+3,而且+4的两年并未导入,所以对于那些失踪年龄而言,它似乎是+3。This creates a problem when the base offset changes - like it has for this time zone. Since it is currently +3, and the two year where it was +4 were not imported, then it will look like it was +3 for those missing years.这是使用 TimeZoneInfo 的好的解决方案。即使您尝试创建自己的自定义时区,您也可能无法将此类更改适用于可用的数据结构。There is no good solution for this using TimeZoneInfo. Even if you try to create your own custom time zones, you'll have trouble fitting this kind of change into the data structures available.幸运的是,还有另一个选项。您可以通过 IANA时区。 org /rel =nofollow> Noda Time 库。Fortunately, there is another option. You can use standard IANA time zones, via the Noda Time library.以下代码使用Noda Time来匹配您在原始代码中所写的内容: p>The following code uses Noda Time to match what you wrote in your original code:DateTimeZone tz = DateTimeZoneProviders.Tzdb.GetSystemDefault();Console.WriteLine(Instant.FromUtc(2012, 1, 1, 0, 0).InZone(tz).LocalDateTime);Console.WriteLine(Instant.FromUtc(2012, 6, 1, 0, 0).InZone(tz).LocalDateTime);Console.WriteLine(Instant.FromUtc(2000, 1, 1, 0, 0).InZone(tz).LocalDateTime);Console.WriteLine(Instant.FromUtc(2000, 6, 1, 0, 0).InZone(tz).LocalDateTime);如果您的本地时区尚未设置为莫斯科,您可以将第一行更改为: / p>If your local time zone is not already set for Moscow, you can change the first line to:DateTimeZone tz = DateTimeZoneProviders.Tzdb["Europe/Moscow"]; OUTPUT:1/1/2012 4:00:00 AM6/1/2012 4:00:00 AM1/1/2000 3:00:00 AM6/1/2000 4:00:00 AM 更新 上述 AdjustmentRule 不跟踪基本偏移量更改的问题已在Microsoft支持文章 KB3012229 ,随后在.NET Framework 4.6和.NET Core中修复。UpdateThe problem described above of AdjustmentRule not tracking base offset changes was described in Microsoft Support article KB3012229, and subsequently fixed in .NET Framework 4.6 and also in .NET Core.在参考资料来源中,一个可以看到 AdjustmentRule 现在保留一个 m_baseUtcOffsetDelta 字段。虽然此字段未通过公共属性公开,但它确实影响到计算,并且如果您使用 FromSerializedString 和 ToSerializedString 方法(如果有人实际使用那些)。In the reference sources, one can see that AdjustmentRule now keeps a m_baseUtcOffsetDelta field. While this field is not exposed via a public property, it does factor in to the calculations, and it does reflect in serialization if you use the FromSerializedString and ToSerializedString methods (if anyone actually uses those). 这篇关于.NET有时区变化的历史吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持! 上岸,阿里云! 07-27 23:28