DateTime dt = new DateTime(1972, 4, 24, 0, 0, 0);
Response.Write("dt: " + dt.ToString("M/d/yyyy h:mm:ss tt") + "<br />");
Response.Write("dt.Kind: " + dt.Kind.ToString() + "<br />");
Response.Write("dt.ToUniversalTime(): " + dt.ToUniversalTime().ToString("M/d/yyyy h:mm:ss tt") + "<br />");
显示器
dt: 4/24/1972 12:00:00 AM
dt.Kind: Unspecified
dt.ToUniversalTime(): 4/24/1972 7:00:00 AM
这是不正确的。 1972年4月24日太平洋时间下午12点实际上是1972年4月24日上午8点UTC。
我已通过iOS的内部UTC日期对话和www.timeanddate.com确认了正确的UTC转换,UTC时间应为早上8点。我做错了吗?
服务器正在&#34; Pacific Time&#34; timezone所以ToUniversalTime应该从太平洋时区转换为UTC,因为Unspecified被视为Local。
答案 0 :(得分:4)
如果您使用的是太平洋标准时间以上的计算机,则可以使用以下代码查看此行为:
DateTime dt = new DateTime(1972, 4, 24, 0, 0, 0);
TimeZoneInfo tz = TimeZoneInfo.FindSystemTimeZoneById("Pacific Standard Time");
Console.WriteLine (TimeZoneInfo.ConvertTimeToUtc(dt, tz));
// 4/24/1972 7:00:00 AM
如果您查看navy.mil's history of daylight saving time,您会注意到以下段落:
1966年的统一时间法案提供了日期的标准化 在美国开始和结束白天时间,但允许在当地 豁免遵守。 该法案规定了白天时间 从4月的最后一个星期日开始,到最后一个星期天结束 10月,转换发生在当地时间凌晨2点。
然后一会儿:
1986年,通过了一项法律,改变了日光的开始日期 从1987年开始到4月的第一个星期天
因此DST切换不是4月的第一个星期日,直到1987年,但由于某些原因,.NET的行为就好像是。
Timeanddate.com's history of DST seems to agree,并列出1972年4月30日(4月的最后一个星期日),因为日期时钟转了一小时(到UTC-7)。
微软在1987年之前的DST调整规则似乎是错误的(and I'm not the only one who thinks so)。
这里有TimeZoneInfo
列出的PST规则:
基本上,微软忽视了历史规则,并选择使用1987年生效的规则来规定在这些规则存在之前发生的日期。
基本上,您的日期(1972年)被微软的TimeZoneInfo
调整规则错误处理。
如果您正在寻找能够更好地处理这些类型的时区规则的库,请查看NodaTime,它正确处理此特定情况:
var pacific = DateTimeZoneProviders.Tzdb["America/Los_Angeles"];
LocalDateTime localDateTime = new LocalDateTime(1972, 4, 24, 0, 0);
ZonedDateTime zonedDateTime = pacific.AtStrictly(localDateTime);
DateTime utcDateTime = zonedDateTime.ToDateTimeUtc();
Console.WriteLine(utcDateTime);
// 4/24/1972 8:00:00 AM