与 AdjustmentRule 相比,.NET TimeZoneInfo 中的意外 DST 偏移
Unexpected DST offset in .NET TimeZoneInfo compared to the AdjustmentRule
我正在尝试为英国切换到 BST 的时间点计算正确的 DST 偏移量,该时间点应该是 2021 年 3 月 28 日凌晨 1 点。
我这里有一个fiddle:https://dotnetfiddle.net/8gdVIG
为了完整起见,这是我的代码 运行:
var timeZoneInfo = TimeZoneInfo.GetSystemTimeZones().FirstOrDefault(tzi => tzi.Id.Equals("Europe/London", StringComparison.InvariantCultureIgnoreCase));
Console.WriteLine($"No. of adjustment rules: {timeZoneInfo.GetAdjustmentRules().Count()}");
var firstRule = timeZoneInfo.GetAdjustmentRules().FirstOrDefault(r => new DateTime(2021,03,28,1,59,0) >= r.DateStart && new DateTime(2021,03,28,1,59,0) <= r.DateEnd);
Console.WriteLine($" Day: {firstRule.DaylightTransitionStart.Day}");
Console.WriteLine($" DayOfWeek: {firstRule.DaylightTransitionStart.DayOfWeek}");
Console.WriteLine($"IsFixedDateRule: {firstRule.DaylightTransitionStart.IsFixedDateRule}");
Console.WriteLine($" Month: {firstRule.DaylightTransitionStart.Month}");
Console.WriteLine($" TimeOfDay: {firstRule.DaylightTransitionStart.TimeOfDay}");
Console.WriteLine($" Week: {firstRule.DaylightTransitionStart.Week}");
Console.WriteLine($"Offset at 01:59 on 2021-03-28: {timeZoneInfo.GetUtcOffset(new DateTime(2021,03,28,1,59,0)).Hours}");
结果为:
No. of adjustment rules: 244
Day: 28
DayOfWeek: Sunday
IsFixedDateRule: True
Month: 3
TimeOfDay: 01/01/0001 01:00:00
Week: 1
Offset at 01:59 on 2021-03-28: 0
然而凌晨 2 点的偏移量是我预计凌晨 1 点的 1 小时。
Console.WriteLine($"Offset at 02:00 on 2021-03-28: {timeZoneInfo.GetUtcOffset(new DateTime(2021,03,28,2,0,0)).Hours}");
输出:
Offset at 02:00 on 2021-03-28: 1
为什么凌晨 1 点的 UTC 偏差不是 1 小时?我真的需要 Noda Time 才能获得正确的本地 DST 偏移量吗?
2021-03-28T01:00:00 在英国时区不存在 - 01:59:00 也不存在。我们跳过 at 凌晨 1 点直接到凌晨 2 点。因此,您的代码中打印的第一个值是无效的 date/time 值。
documentation(令人惊讶地)清楚这一点:
If dateTime
is invalid, this method returns a TimeSpan object that reflects the difference between UTC and the time zone's standard time.
并且由于英国的标准时间与UTC相同,打印0是正确的。
我正在尝试为英国切换到 BST 的时间点计算正确的 DST 偏移量,该时间点应该是 2021 年 3 月 28 日凌晨 1 点。
我这里有一个fiddle:https://dotnetfiddle.net/8gdVIG
为了完整起见,这是我的代码 运行:
var timeZoneInfo = TimeZoneInfo.GetSystemTimeZones().FirstOrDefault(tzi => tzi.Id.Equals("Europe/London", StringComparison.InvariantCultureIgnoreCase));
Console.WriteLine($"No. of adjustment rules: {timeZoneInfo.GetAdjustmentRules().Count()}");
var firstRule = timeZoneInfo.GetAdjustmentRules().FirstOrDefault(r => new DateTime(2021,03,28,1,59,0) >= r.DateStart && new DateTime(2021,03,28,1,59,0) <= r.DateEnd);
Console.WriteLine($" Day: {firstRule.DaylightTransitionStart.Day}");
Console.WriteLine($" DayOfWeek: {firstRule.DaylightTransitionStart.DayOfWeek}");
Console.WriteLine($"IsFixedDateRule: {firstRule.DaylightTransitionStart.IsFixedDateRule}");
Console.WriteLine($" Month: {firstRule.DaylightTransitionStart.Month}");
Console.WriteLine($" TimeOfDay: {firstRule.DaylightTransitionStart.TimeOfDay}");
Console.WriteLine($" Week: {firstRule.DaylightTransitionStart.Week}");
Console.WriteLine($"Offset at 01:59 on 2021-03-28: {timeZoneInfo.GetUtcOffset(new DateTime(2021,03,28,1,59,0)).Hours}");
结果为:
No. of adjustment rules: 244
Day: 28
DayOfWeek: Sunday
IsFixedDateRule: True
Month: 3
TimeOfDay: 01/01/0001 01:00:00
Week: 1
Offset at 01:59 on 2021-03-28: 0
然而凌晨 2 点的偏移量是我预计凌晨 1 点的 1 小时。
Console.WriteLine($"Offset at 02:00 on 2021-03-28: {timeZoneInfo.GetUtcOffset(new DateTime(2021,03,28,2,0,0)).Hours}");
输出:
Offset at 02:00 on 2021-03-28: 1
为什么凌晨 1 点的 UTC 偏差不是 1 小时?我真的需要 Noda Time 才能获得正确的本地 DST 偏移量吗?
2021-03-28T01:00:00 在英国时区不存在 - 01:59:00 也不存在。我们跳过 at 凌晨 1 点直接到凌晨 2 点。因此,您的代码中打印的第一个值是无效的 date/time 值。
documentation(令人惊讶地)清楚这一点:
If
dateTime
is invalid, this method returns a TimeSpan object that reflects the difference between UTC and the time zone's standard time.
并且由于英国的标准时间与UTC相同,打印0是正确的。