Windows XP上的DateTime.ToLocalTime

5

.NET的DateTime.ToLocalTime方法文档中说明:

在Windows XP系统上,ToLocalTime方法仅识别当前调整规则,从UTC转换为本地时间。因此,在当前调整规则生效之前的期间进行转换可能无法准确反映UTC和本地时间之间的差异。

我正在Windows 7上开发,但部署到混合环境中。如何提供一致且正确的实现,以匹配ToLocalTime的Windows 7行为?

编辑

我进行了测试:

static void Main()
{
    // 8 AM in July, UTC. That would have been DST, so 3 AM CDT.
    var dstDate = new DateTime(2010, 7, 1, 8, 0, 0, DateTimeKind.Utc);

    // 8 AM in December, UTC. Not DST, so 2 AM CST.
    var nonDstDate = new DateTime(2010, 12, 1, 8, 0, 0, DateTimeKind.Utc);

    Log("DST Date ToLocalTime: " + dstDate.ToLocalTime());
    Log("DST Date ConvertTimeFromUtc: " + ConvertTimeFromUtc(dstDate));
    Log("Expected: 3 AM July 1 2010");

    Log(string.Empty);

    Log("Non-DST Date ToLocalTime: " + nonDstDate.ToLocalTime());
    Log("Non-DST Date ConvertTimeFromUtc: " + ConvertTimeFromUtc(nonDstDate));
    Log("Expected: 2 AM December 1 2010");

    Log(string.Empty);

    Log("Date ToLocalTime Kind: " + dstDate.ToLocalTime().Kind);
    Log("Date ConvertTimeFromUtc Kind: " + ConvertTimeFromUtc(dstDate).Kind);
}

private static void Log(string message)
{
    Console.WriteLine(message);
}

private static DateTime ConvertTimeFromUtc(DateTime utcDateTime)
{
    return
        DateTime.SpecifyKind(
            TimeZoneInfo.ConvertTimeFromUtc(
                utcDateTime,
                TimeZoneInfo.FindSystemTimeZoneById(TimeZoneInfo.Local.Id)),
            DateTimeKind.Local);
}

结果在XP Pro 32位,SP3(作为VM)和Windows 7 Enterprise 64位下完全相同:
DST日期ToLocalTime: 7/1/2010 3:00:00 AM DST日期ConvertTimeFromUtc: 7/1/2010 3:00:00 AM 预期: 2010年7月1日上午3点
非DST日期ToLocalTime: 12/1/2010 2:00:00 AM 非DST日期ConvertTimeFromUtc: 12/1/2010 2:00:00 AM 预期: 2010年12月1日上午2点
日期ToLocalTime类型: 本地 日期ConvertTimeFromUtc类型: 本地
文档有误吗?我可以直接调用ToLocalTime吗?
编辑2
我们在实际的XP系统上运行了这个程序(而不是虚拟机),并得到了完全相同的结果。我的测试用例正确吗?有人能提供一个结果不同的案例吗?
2个回答

5
在Windows XP系统上,ToLocalTime方法在从UTC转换为本地时间时仅识别当前的调整规则。因此,在当前调整规则生效之前的时间段内进行转换可能无法准确反映UTC和本地时间之间的差异。
美国于2007年更改了夏令时的调整规则。
  • 2006年: 从4月第一个星期日开始,到10月最后一个星期日结束。
  • 2007年: 从3月第二个星期日开始,到11月第一个星期日结束。
问题在于他们对所有日期都遵循2007年的规则,而不仅仅是2007年之后的日期。夏令时规则已经20年没有改变了,Windows XP只是没有不同年份的概念。它将认为2006年10月31日处于夏令时状态,但实际上并非如此。
如果你只涉及2007年之后的日期,那么就没问题了,不需要特别处理。如果你涉及2006年或之前的日期,则需要检查年份,并手动应用DST偏移量。

啊!当他们谈到调整规则时,我以为他们是指“我现在应该应用DST调整”。我刚刚发现这个链接,它说你是正确的。谢谢! - TrueWill

1
你可以使用 System.TimeZoneInfo.ConvertTime(DateTime, TimeZoneInfo, TimeZoneInfo) 方法将时间从源时区转换为用户的本地时区。

谢谢你指导我正确的方向,但这只是答案的一半。我在链接找到了WinXP的笔记。也许可以使用TimeZoneInfo.ConvertTimeFromUtc(utcDate, TimeZoneInfo.FindSystemTimeZoneById(TimeZoneInfo.Local.Id)) - TrueWill

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接