DateTime.ToLocalTime()行为随服务器2008R2上的.NET 4.5而更改

本文关键字:NET 上的 2008R2 服务器 ToLocalTime DateTime | 更新日期: 2023-09-27 18:28:09

我们在.NET 4.5和System.DateTime中看到了奇怪的行为。与.NET 4.0相比,ToLocalTime()在应用于Kind=Utc的DateTime对象时,在使用.NET 4.5的Server 2008R2计算机上的行为似乎有所不同。更奇怪的是,这个问题并没有在安装了.NET 4.5的开发人员电脑上表现出来。

有人能解释这种行为吗?我在微软网站上找不到任何错误报告。我们可以使用更复杂的方法来转换有效的时间,但很难确保将来不会有人使用.ToLocalTime()。

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

unixEpoch 621355968000000000 Utc 
asLocal1 635121441023588986 Local 
asLocal2 635121441023588986 Unspecified

生产服务器1-服务器2008R2,.NET 4.0

unixEpoch 621355968000000000 Utc 
asLocal1 635121441023588986 Local 
asLocal2 635121441023588986 Unspecified

生产服务器2-服务器2008R2,.NET 4.5作为独立包安装

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

除了安装了.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();
      }
   }
}

DateTime.ToLocalTime()行为随服务器2008R2上的.NET 4.5而更改

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

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

这是非常难追踪的,我还没有看到任何其他网络论坛提到数据库更新和utc这样基本的东西之间的联系。ToLocalTime()在2013年8月的日期上失败了,在美国东部,由于立法等原因,最近的边界发生了变化。仍然想知道为什么在更多的地方没有看到这种情况?