我有一些过时的代码试图解释夏令时造成的时间变化,如下所示:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication2
{
class Program
{
static void Main(string[] args)
{
for (int i = 1; i <= 31; i++)
{
DateTime dt = new DateTime(1960, 3, i, 0, 0, 0);
Console.WriteLine(dt.ToUniversalTime());
}
Console.WriteLine();
for (int i = 1; i <= 30; i++)
{
DateTime dt = new DateTime(1960, 4, i, 0, 0, 0);
Console.WriteLine(dt.ToUniversalTime());
}
Console.ReadKey();
}
}
}
此代码遍历1960年3月和4月的日期并打印日期时间。 但是,这并没有正确地说明1960年的时间变化,我相信因为时间变化的日期不同了。我试图使用TimeZoneInfo类来解决这个问题。我将代码更改为以下内容:
class Program
{
static void Main(string[] args)
{
for (int i = 1; i <= 31; i++)
{
DateTime dt = new DateTime(1960, 3, i, 0, 0, 0);
var tz = TimeZoneInfo.Local;
var utcOffset = new DateTimeOffset(dt, TimeSpan.Zero);
//use timeZoneInfo class to account for dlst offset
Console.WriteLine(utcOffset.ToOffset(tz.GetUtcOffset(utcOffset)));
}
Console.WriteLine();
for (int i = 1; i <= 30; i++)
{
DateTime dt = new DateTime(1960, 4, i, 0, 0, 0);
var tz = TimeZoneInfo.Local;
var utcOffset = new DateTimeOffset(dt, TimeSpan.Zero);
//use timeZoneInfo class to account for dlst offset
Console.WriteLine(utcOffset.ToOffset(tz.GetUtcOffset(utcOffset)));
}
Console.ReadKey();
}
}
不幸的是,这是打印出来的:
表明夏令时在4月3日下午4点发生变化,而应该在4月24日凌晨2点切换。我错过了什么才能正确解释夏令时?
修改 我现在的时区是东部。
答案 0 :(得分:2)
看起来Windows时区信息与我通过TZDB预期的不一致。这是一个使用Noda Time显示〜1960年和1965年之间所有转换的程序,包括BCL TimeZoneInfo(包装)和TZDB 2012i数据:
using System;
using NodaTime;
class Test
{
static void Main()
{
var bcl = DateTimeZoneProviders.Bcl["Eastern Standard Time"];
var tzdb = DateTimeZoneProviders.Tzdb["America/New_York"];
ShowTransitions(bcl);
ShowTransitions(tzdb);
}
static void ShowTransitions(DateTimeZone zone)
{
Console.WriteLine("Transitions for {0}", zone.Id);
Instant start = Instant.FromUtc(1960, 1, 1, 0, 0);
Instant end = Instant.FromUtc(1965, 1, 1, 0, 0);
var interval = zone.GetZoneInterval(start);
while (interval.Start < end)
{
Console.WriteLine(interval.Start);
interval = zone.GetZoneInterval(interval.End);
}
Console.WriteLine();
}
}
输出:
Transitions for Eastern Standard Time
1959-10-25T06:00:00Z
1960-04-03T07:00:00Z
1960-10-30T06:00:00Z
1961-04-02T07:00:00Z
1961-10-29T06:00:00Z
1962-04-01T07:00:00Z
1962-10-28T06:00:00Z
1963-04-07T07:00:00Z
1963-10-27T06:00:00Z
1964-04-05T07:00:00Z
1964-10-25T06:00:00Z
Transitions for America/Toronto
1959-10-25T06:00:00Z
1960-04-24T07:00:00Z
1960-10-30T06:00:00Z
1961-04-30T07:00:00Z
1961-10-29T06:00:00Z
1962-04-29T07:00:00Z
1962-10-28T06:00:00Z
1963-04-28T07:00:00Z
1963-10-27T06:00:00Z
1964-04-26T07:00:00Z
1964-10-25T06:00:00Z
还有其他时区ID映射到“东部标准时间”,但我没有找到任何与Windows行为匹配的时区。
我认为这不是TimeZoneInfo
错误 - 我认为这是基础Windows时区数据中的一个潜在问题。
如果你想匹配TZDB数据,你当然可以使用Noda Time:)
答案 1 :(得分:1)
有一个dt.IsDaylightSavingTime()。在1960年,它改变了4/4(比你的晚一天),但我是CST。对于2012年,它在我的系统上是正确的。这可能是一个错误。它可能只是那一年或所有年份直到X.
我认为这解释了它:
“在20世纪60年代早期,遵守夏令时非常不一致,有大量的时间观察,并且没有就何时更换时钟达成一致。”
“1966年统一时间法案”在整个美国建立了统一(在每个时区内)夏令时制度。“