Windows 7时区规则是否存在缺陷

时间:2018-08-08 13:09:45

标签: c# windows timezone timezone-offset

英国夏令时每年每年三月和十月调整时钟。在1968年至1971年期间,英国将BST作为一种永久选择进行了试验,因此1968年3月提出了1个小时的时钟,直到1971年10月才恢复原状。

我正在用Javascript创建日期,将其序列化为JSON并发布到WebApi。

当前使用Windows 7作为开发环境,Windows无法将该时期识别为BST。例如,1970年1月1日应该是夏令时,但是

new System.DateTime(1970, 01, 01, 00, 00, 00).IsDaylightSavingTime();

返回假。

还...

System.TimeZone.CurrentTimeZone.GetDaylightChanges(1970)
{System.Globalization.DaylightTime}
    Delta: {01:00:00}
    End: {25/10/1970 02:00:00}
    Start: {29/03/1970 01:00:00}

1970年应该有一条规则涵盖整个年份,因为全年都是BST。

是否有补丁可以纠正Windows中的漏洞?

3 个答案:

答案 0 :(得分:2)

更新

毕竟存在一个错误,或者说GMT Standard Time不包含英国特定的规则。在1968年到1970年之间,英国的偏移量更改为+1:00,并且没有夏令时。

真实问题是该时期内英国的偏移量是错误的:

var date= new DateTime(1970,1,1,0,0,0,DateTimeKind.Local);
var tzi = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
var offset=tzi.GetUtcOffset(date);

offset00:00:00。糟糕!

对于1970-08-01,偏移量为01:00:00,而IsDaylightSavingTime()返回True。

PS: SQL Server的AT TIME ZONE使用 Windows 时区名称。这可能是历史数据问题的更大根源。

原始

没有错误。当整年有一个单个偏移量时,谈论夏时制就没有意义了。

IANA时区数据库显示1970-01-01没有使用DST。偏移量为+1:00。使用NodaTime:

var london = DateTimeZoneProviders.Tzdb["Europe/London"];

// Time zone conversions
var localDate = new LocalDateTime(1970, 1, 1, 0, 0, 00);
var before = london.AtStrictly(localDate);

Console.WriteLine($"{before} {before.IsDaylightSavingTime()} {before.Offset}");

这将返回:

1970-01-01T00:00:00 Europe/London (+01) DST:False +01

对于1971-11-01,结果是:

1971-11-01T00:00:00 Europe/London (+00) DST:False +00

那时,偏移量从+1:00更改为+00:00,并重新引入了DST规则。

对于夏季日期,结果更有趣。

1971-07-30返回:

1971-07-30T00:00:00 Europe/London (+01) DST:False +01

这是正确的-该日期没有生效的DST规则。偏移量固定为+1。

1972-07-30返回:

1972-07-30T00:00:00 Europe/London (+01) DST:True +01

偏移量是相同的,因为DST规则在该日期生效。

答案 1 :(得分:2)

Windows在英国没有单独的时区。 Windows在英国使用的时区(“ GMT标准时间”)与爱尔兰和葡萄牙共享。

这就是为什么未反映仅适用于英国的历史偏差的原因。

即使在最近的200年中,国家的边界​​也发生了很大变化,直到最近(仅几十年前),欧洲很小的区域才有了自己的时区定义,并且它们经常变化。 Windows无法反映该复杂信息。如果您需要这些信息,则需要使用专用的数据库。

答案 2 :(得分:1)

如评论中所述,您所提供的代码正在使用您正在运行该代码的计算机上的当前时区。可能是英国,但这不是一个好主意。以下代码考虑了上面的注释:

var tzi = TimeZoneInfo.FindSystemTimeZoneById("GMT Standard Time");
var dt = new DateTime(1970, 1, 2, 0, 0, 0, DateTimeKind.Utc);

var isDlt = tzi.IsDaylightSavingTime(dt);

这也会返回false,因此您所陈述的错误确实存在。我非常怀疑是否有补丁,但是如果您有这样的想法,可以很容易地编写一个扩展方法,该方法使用IANA数据库确定给定日期是否在夏令时。

您可能还希望查看TimeZoneInfo.GetAdjustmentRules-https://msdn.microsoft.com/en-us/library/system.timezoneinfo.getadjustmentrules(v=vs.110).aspx

的文档