在Server 2008R2上使用.NET 4.5更改DateTime.ToLocalTime()行为?

Dav*_*ore 6 .net c# datetime

我们看到.NET 4.5和System.DateTime的奇怪行为.应用于具有Kind = Utc的DateTime对象时,ToLocalTime()的行为在使用.NET 4.5的Server 2008R2计算机上与.NET 4.0相比时显得不同.更奇怪的是,安装了.NET 4.5的开发者PC上并没有出现这个问题.

有没有人对这种行为有解释?我无法在Microsoft网站上发现任何错误报告.我们可以使用更复杂的方法来转换有效的时间,但是很难确保将来没有人使用.ToLocalTime().

开发人员PC - 在VS2012安装期间安装的Windows 7,VS2012,.NET 4.5:

unixEpoch 621355968000000000 Utc 
asLocal1 635121441023588986 Local 
asLocal2 635121441023588986 Unspecified
Run Code Online (Sandbox Code Playgroud)

Production Server 1 - Server 2008R2,.NET 4.0

unixEpoch 621355968000000000 Utc 
asLocal1 635121441023588986 Local 
asLocal2 635121441023588986 Unspecified
Run Code Online (Sandbox Code Playgroud)

Production Server 2 - 作为独立软件包安装的Server 2008R2,.NET 4.5

unixEpoch 621355968000000000 Utc
asLocal1 ***635121405023588986*** Local
asLocal2 635121441023588986 Unspecified
Run Code Online (Sandbox Code Playgroud)

除了安装.NET 4.5之外,生产服务器1和2是相同的.当在全球几个不同的本地时区运行时,问题就会出现.

演示此问题的示例代码:

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();

      }
   }
}
Run Code Online (Sandbox Code Playgroud)

Dav*_*ore 2

当以下修补程序应用于运行 2008R2 的服务器时,此问题就会消失: http://support.microsoft.com/kb/2863058/en-us

看来,在幕后,DateTime.ToLocalTime() 使用的查找技术会失败,除非已应用该修补程序中包含的时区数据库更新。

这非常难以追踪,而且我还没有看到任何其他网络论坛提到该数据库更新与 utc.ToLocalTime() 之类的基本内容之间的联系,无法获取 2013 年 8 月的日期,没有靠近最近发生变化的边界由于美国东部的立法等原因,您仍然想知道为什么在更多地方没有看到这种情况?