Changing DateTime.ToLocalTime () date from .NET 4.5 on 2008R2 server?

We observe strange behavior with .NET 4.5 and System.DateTime. The behavior of ToLocalTime () when applied to DateTime objects using Kind = Utc looks different on Server 2008R2 servers with .NET 4.5 compared to .NET 4.0. Even stranger, the problem does not occur on development computers with .NET 4.5 installed.

Does anyone have an explanation for this behavior? I cannot show error reports on Microsoft sites. We can use a more sophisticated approach to transform the time, which works, but it's hard to guarantee that no one will ever use .ToLocalTime () in the future.

Developer PC - Windows 7, VS2012, .NET 4.5 installed during VS2012 installation:

unixEpoch 621355968000000000 Utc asLocal1 635121441023588986 Local asLocal2 635121441023588986 Unspecified 

Production Server 1 - Server 2008R2, .NET 4.0

 unixEpoch 621355968000000000 Utc asLocal1 635121441023588986 Local asLocal2 635121441023588986 Unspecified 

Production Server 2 - Server 2008R2, .NET 4.5 installed as a separate package

 unixEpoch 621355968000000000 Utc asLocal1 ***635121405023588986*** Local asLocal2 635121441023588986 Unspecified 

In addition to installing .NET 4.5, production servers 1 and 2 are identical. The problem manifests itself when launched in several different local time zones around the world.

Sample code demonstrating the problem:

 using System; using NUnit.Framework; namespace DateTimeToLocal { [TestFixture] public class DateTimeFixture { private const long unixTimeInNanos = 1376561702358898611; [Test] public void Demonstrate() { DateTime unixEpoch = new DateTime(1970, 01, 01, 0, 0, 0, DateTimeKind.Utc); DateTime utc = unixEpoch.AddTicks(unixTimeInNanos / 100); // Method 1 - doesn't work on 2008R2 with .NET 4.5 DateTime asLocal1 = utc.ToLocalTime(); // Method 2 - works across all .NET 4.0 and .NET 4.5 TimeZoneInfo localTz = TimeZoneInfo.FindSystemTimeZoneById(TimeZoneInfo.Local.StandardName); DateTime asLocal2 = TimeZoneInfo.ConvertTimeFromUtc(utc, localTz); Console.WriteLine("unixEpoch {0} {1}", unixEpoch.Ticks,unixEpoch.Kind); Console.WriteLine("asLocal1 {0} {1}", asLocal1.Ticks, asLocal1.Kind); Console.WriteLine("asLocal2 {0} {1}", asLocal2.Ticks, asLocal2.Kind); Assert.AreEqual(asLocal1, asLocal2); } public static void Main(string[] args) { var t = new DateTimeFixture(); t.Demonstrate(); } } } 
+6
source share
1 answer

This problem disappears when the following hotfix is ​​applied to a server with 2008R2: http://support.microsoft.com/kb/2863058/en-us

It appears that under the hood, DateTime.ToLocalTime () uses a search technique that fails if the time zone database update contained in this hotfix has not been installed.

It was extremely difficult to track, and I did not see ANY other web forum mention the connection between this database update and something as fundamental as utc.ToLocalTime (), which did not go through dates in August 2013, where there is no nearby is a border that has changed due to legislation, etc. in eastern usa. I wonder how exactly this is not visible to more places?

+2
source

Source: https://habr.com/ru/post/952044/


All Articles