为什么这个时区可以纠正夏令时

时间:2016-02-16 21:36:43

标签: c# timezone

2016年东部标准时间的夏令时于2016年3月13日凌晨2点开始。此时时钟设置回到凌晨1点,使凌晨2点无效。

此代码块报告dateTime2 var。

的凌晨2点的错误
TimeZoneInfo timeZoneInfo1;
timeZoneInfo1 = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");
var dateTime1 = TimeZoneInfo.ConvertTime(new DateTime(2016, 3, 13, 1, 0, 0), timeZoneInfo1);
var dateTime2 = TimeZoneInfo.ConvertTime(new DateTime(2016, 3, 13, 2, 0, 0), timeZoneInfo1);        //Reports invalid date error
var dateTime3 = TimeZoneInfo.ConvertTime(new DateTime(2016, 3, 13, 3, 0, 0), timeZoneInfo1);

但是,在下面的时区"太平洋SA标准时间"示例中,1990年的夏令时从10/13/1990 @ 11pm开始。这应该使dateTime4 10/13/1990 @ 11pm成为无效的日期/时间。

相反,dateTime4作为有效日期/时间返回。

此外,dateTime5将在10/14/1990 @ 1am返回,自动跳过午夜时段。

并且dateTime6在我预期的时候返回到10/14/1990 @ 2am而不是凌晨1点。

TimeZoneInfo timeZoneInfo2;
timeZoneInfo2 = TimeZoneInfo.FindSystemTimeZoneById("Pacific SA Standard Time");
var dateTime4 = TimeZoneInfo.ConvertTime(new DateTime(1990, 10, 13, 23, 0, 0), timeZoneInfo2);      //10-14-1990@11pm
var dateTime5 = TimeZoneInfo.ConvertTime(new DateTime(1990, 10, 14, 0, 0, 0), timeZoneInfo2);       //10-14-1990@1am
var dateTime6 = TimeZoneInfo.ConvertTime(new DateTime(1990, 10, 14, 1, 0, 0), timeZoneInfo2);       //10-14-1990@2am

TimeZoneInfo.ConvertTime的两种工作方式是什么原因?

我正在使用VS2010。

1 个答案:

答案 0 :(得分:4)

一些事情:

  • Pacific SA Standard Time是具有英文显示名称(UTC-03:00) Santiago的Windows时区的ID。那是智利的圣地亚哥。

  • Windows中此区域最早的条目是2007年。它没有1990年的数据,因此错误地假设2007之前的任何内容与2007年相同。通常,Microsoft时区没有广泛的历史。

    • 请参阅timezone tag wiki,其中标题为“Microsoft时区数据库”的部分。它描述了它们的工作原理,在注册表中可以看到它们的详细信息,以及使用它们的优缺点。
  • 智利每年都有不同的DST日期。 See here for year-to-year details from that period

  • In 1990, DST started on September 16th at 12:00 AM。从12:00到凌晨1:00的小时被跳过。根据您的建议,不是10月13日晚上11点到中午12:00。

  • 如果历史准确性对您的应用程序很重要,请不要使用Windows时区标识符或TimeZoneInfo类。他们不能胜任这项特殊任务。相反,请使用IANA标识符(例如America/SantiagoAmerica/New_York),并使用Noda Time。使用Noda Time还有许多其他优点。

  • 要回答最后两个问题,dateTime5dateTime6是在未指定DateTimeKind的情况下创建的,因此默认情况下为DateTimeKind.Unspecified。然后,当您调用ConvertTime函数时,根据备注in the MSDN,假定该值来自您的本地时区。

    为清楚起见,您的代码正在将这些日期本地时区转换为您指定的时区。

    因此,如果这些日期在您的本地时区(无论可能是什么)中有效,那么它们确实可以被转换,并且不会抛出异常。如果结果是一个小时不同,那么这意味着您当地的时区距离Windows认为圣地亚哥当时的时间还有一小时。