Categories
Uncategorized

为什么夏令时不直观

夏令时在北美和欧洲的大部分地区将于本周末结束,因此现在是讨论夏令时和时间戳的整个问题的好时机。

一个常见的抱怨是,所有时区转换函数(例如:FileTimeToLocalFileTime)都应用当前夏令时 (DST) 偏差,而不是在相关时间有效的偏差。

例如,假设您有一个 FILETIME 结构,该结构表示“2000 年 1 月 1 日 12:00AM”。如果您在夏季在RDM,这将转换为“1999年12月31日下午5:00”,相差七个小时,即使当时RDM和UTC之间的时差是八个小时。也就是说,当伦敦人庆祝新年时,RDM是下午4点,而不是下午5点。

原因是时间从“2000 年 1 月 1 日 12:00 AM UTC”转换为“1999 年 12 月 31 日下午 5:00 PDT”。因此,从技术上讲,转换是正确的。当然,1999年12月31日在RDM没有人使用PDT。每个人都在PST上。

为什么时区转换函数不使用适合一年中时间的时区?

一个原因是,这意味着 FileTimeToLocalFileTimeLocalFileTimeToFileTime 将不再是彼此的反转。如果在从标准时间切换到夏令时期间的“边缘小时”期间有一个本地时间,则它没有相应的 UTC 时间,因为没有本地时间凌晨 2:30 这样的东西。(时钟从凌晨2点跳到凌晨3点。同样,在从夏令时切换回标准时间期间,本地时间凌晨 2:30 将具有个相应的 UTC 时间。

另一个原因是,有关夏令时的法律在不断变化。例如,如果上面示例中的年份是 1977 年而不是 2000 年,则转换是正确的,因为由于能源危机,美国全年都在使用夏令时。当然,此信息不会在TIME_ZONE_INFORMATION结构中的任何位置进行编码。同样,在第二次世界大战期间,美国全年都在使用DST。在 1945 年至 1966 年间,DST 规则因地区而异。

即使在今天,DST 规则也在不断变化。以色列的DST转换日期由以色列议会逐年决定。因此,当天没有确定性的公式,因此无法提前知道它。

FileInfo.LastWriteTime.ToString(也就是“f”) 的输出与您在属性表中看到的文件(上次写入 DST 转换的另一侧)的内容进行比较。例如,假设文件上次修改时间为 10 月 17 日,在 DST 期间,但 DST 当前无效。资源管理器的文件属性报告 2003 年 10 月 17 日星期四上午 8:45:38,但是 。NETs FileInfo 报道于 2003 年 10 月 17 日星期四上午 9:45。

并且值得注意的是:Win32 不会尝试猜测其他时间的时区规则是否有效。因此,Win32 说:“太平洋标准时间 2002 年 10 月 17 日星期四上午 8:45:38”。注意:太平洋标准时间。尽管 10 月 17 日是太平洋夏令时,但 Win32 仍将该时间显示为标准时间,因为现在是标准时间。

.NET 说,“Okay,如果现在生效的规则也在 2003 年 10 月 17 日生效,那么这将是夏令时”,因此它显示“2003 年 10 月 17 日星期四,太平洋夏令时上午 9:45”。

因此,.NET 给出了一个更直观正确的值,但也可能不正确,并且该值不可逆。Win32 给出的值在直观上是不正确的,但严格正确。