我正在尝试在C#应用程序中控制夏令时,而不是让Windows执行此操作。 (我不会在这里说出原因)。
所以我在日期和时间设置(Windows7)中删除了“自动调整夏令时”复选标记
为了证明我所面临的问题,我编写了这段小代码。
TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById(TimeZoneInfo.Local.Id);
// "Romance Standard Time"
var rule = tzi.GetAdjustmentRules()[0];
System.Globalization.CultureInfo.CurrentCulture.ClearCachedData();
var timestampToWorkOn = DateTime.Now;
Console.WriteLine("Timezone is: " + tzi.ToString());
Console.WriteLine("Timezone id is: " + tzi.Id);
Console.WriteLine("Timestamp right now: " + timestampToWorkOn.ToString("yyyy-MM-dd HH:mm"));
Console.WriteLine("Rule for change says: " + rule.DaylightTransitionEnd.TimeOfDay.ToString("HH:mm"));
Console.WriteLine("Is it dst: " + tzi.IsDaylightSavingTime(timestampToWorkOn));
Console.WriteLine("Is it ambiguous:" + tzi.IsAmbiguousTime(timestampToWorkOn));
由于从dst到正常时间的过渡应该发生在3:00,我怀疑从凌晨2点到凌晨3点的时间是不明确的。 但是在1:54运行代码的结果是:
时区是:(UTC + 01:00)布鲁塞尔,哥本哈根,马德里,巴黎
时区ID是:浪漫标准时间
时间戳现在:2013-10-27 01:54
变更规则说:03:00
它是dst:False
这是不明确的:真的
我可能会遗漏一些东西。 我希望dst是真实的,模糊不清的,但这是相反的方式。
很难保持概述,但为什么我会看到这种行为?
答案 0 :(得分:0)
您应该阅读this blog post,其中详细说明了Windows注册表设置如何受时区选择和“自动调整...”复选框的影响。它还介绍了TimeZoneInfo
如何使用这些设置。具体来说,它声明:
恕我直言,没有充分的理由清除该复选框并禁用夏令时。它将计算机的时钟置于人为的现实中。如果禁用本地时区的夏令时,
TimeZoneInfo.Local
将返回一个TimeTimeZoneInfo.SupportsDaylightSavingTime
设置为False的TimeZoneInfo对象。使用此TimeZoneInfo.ConvertTime(...)
实例的任何TimeZoneInfo
次呼叫都不会将夏令时考虑在内。
如果您在服务器上运行代码,则应该将服务器的时区设置为UTC。这将使Windows无需更新计算机的BIOS以进行转换,并且可以让其他服务器的本地时间戳排成一行。
关于您的代码,请注意DateTime.Now
的结果为.Kind == DateTimeKind.Local
,并且与您之前使用的时区无关。您恰好报告了本地时区,但如果您使用的是其他时区,则代码将不正确。
当您获得调整规则时,您假设当地时区将有一个。有些(如亚利桑那州)没有任何DST,因此它们没有调整规则,并且您获得了索引超出范围的异常(因为[0]
)。
另外,只是挑剔但是,
// This line is self redundant.
TimeZoneInfo tzi = TimeZoneInfo.FindSystemTimeZoneById(TimeZoneInfo.Local.Id);
// It can be reduced to:
TimeZoneInfo tzi = TimeZoneInfo.Local;
但真正的问题是因为你关闭了“调整DST”选项,所以DateTime没有被转换为正确的UTC时刻,以便确定它是否含糊不清。如果你深入研究DateTime.IsAmbiguousTime()
的.Net源代码(反编译或符号源),你会发现它使用TimeZoneInfo.ConvertTime()
,它(根据前面的引用)在框中没有考虑DST未经检查,从而使结果不正确(基本上是1小时)。
您还应查看TimeZoneInfo.IsAmbiguousTime
的MSDN说明,其中描述了输入的Kind
如何影响输出结果。