为什么这个时区要修正夏令时

Jer*_*rry 1 c# timezone

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

此代码块报告 dateTime2 变量在凌晨 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);
Run Code Online (Sandbox Code Playgroud)

但是,在以下时区“南太平洋标准时间”的示例中,1990 年的夏令时于 10/13/1990@11pm 开始。这将使 dateTime4 10/13/1990@11pm 成为无效的日期/时间。

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

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

dateTime6 返回为 10/14/1990@2am,而不是我预期的 1am。

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
Run Code Online (Sandbox Code Playgroud)

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

我用的是VS2010。

Mat*_*int 5

一些东西:

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

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

    • 请参阅时区标签 wiki,其中有一个标题为“Microsoft 时区数据库”的部分。它描述了它们的工作原理、您可以在注册表中查看它们的详细信息以及使用它们的优缺点。
  • 智利有着每年不同夏令时日期的悠久历史。 请参阅此处了解该时期的逐年详细信息

  • 1990 年,夏令时于 9 月 16 日中午 12:00 开始。跳过 12:00 到 1:00 AM 的时间。不是您建议的 10 月 13 日晚上 11:00 到中午 12:00。

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

  • 要回答最后两个问题,dateTime5dateTime6是在没有指定的情况下创建的DateTimeKind,因此它们DateTimeKind.Unspecified默认具有。然后,当您调用该函数时,根据MSDN 中的ConvertTime注释,该值被假定源自您的本地时区。

    需要明确的是,您的代码正在将这些日期您的本地时区转换您指定的时区。

    因此,如果这些日期在您当地的时区(无论是什么)有效,那么它们确实可以转换并且不会引发异常。如果结果相差一个小时,则意味着您的本地时区与 Windows 认为的圣地亚哥当时的时区相差一个小时。