将 DateTime 转换为 UTC 时的调整规则是什么?
What is this about adjustment rules when converting DateTime to UTC?
在 TimeZoneInfo.ConvertTimeToUtc()
的 MSDN 页面中,有这个信息框:
If the current computer's local time zone includes multiple adjustment rules, this overload of the ConvertTimeToUtc method can return results that differ from the TimeZone.ToUniversalTime and DateTime.ToUniversalTime methods. TimeZone.ToUniversalTime always applies the current adjustment rule to time zone conversion, whether or not dateTime lies within its date range. And when executing on .NET Framework 3.5, DateTime.ToUniversalTime also applies the current adjustment rule to time zone conversion, whether or not dateTime lies within its date range.
我不确定我是否理解这意味着什么。这些调整规则是什么,ConvertTimeToUtc()
和TimeZone.ToUniversalTime()
之间的结果有何不同?
这是一个例子。在撰写本文时,我的计算机 post 设置为美国太平洋时区,今天是 2015 年 3 月 2 日。目前是太平洋标准时间(或 PST),比 UTC 晚 8 小时。
DateTime dt = new DateTime(2006, 4, 1, 0, 0, 0);
TimeZoneInfo tzi = TimeZoneInfo.Local;
DateTime utc = TimeZoneInfo.ConvertTimeToUtc(dt, tzi);
在上面的代码中,我将另一个值(2006 年 4 月 1 日午夜)从我的时区转换为 UTC。在那个特定的时间点,太平洋标准时间(或 PST)生效。上面的代码使用了 TimeZoneInfo
,这是正确的做法。输出是 2006 年 4 月 1 日 8:00 AM UTC。
现在看这段代码:
DateTime dt = new DateTime(2006, 4, 1, 0, 0, 0);
TimeZone tz = TimeZone.CurrentTimeZone;
DateTime utc = tz.ToUniversalTime(dt);
它似乎做几乎相同的事情。但它 returns 7:00 AM UTC 的错误值。
发生这种情况是因为美国 changed it's daylight saving time 规则于 2007 年生效。在示例中的日期,DST 未根据当时的规则生效,但如果当前 规则当时就位。
很简单,TimeZoneInfo
对象知道此更改,但 TimeZone
对象不知道。它错误地假设当前规则始终有效。
TimeZone
class 上的其他方法也会发生同样的事情,这就是为什么 the MSDN reference 说:
Important
Whenever possible, use the TimeZoneInfo
class instead of the TimeZone
class.
此外,TimeZone
class 已从新 .Net CoreCLR 项目中 删除。
关于 "adjustment rules" - MSDN 备注专门指的是 TimeZoneInfo.AdjustmentRule
class,它用于跟踪可能定期或不定期发生的时区偏移变化在一个时区内。夏令时是一种可能发生的变化类型,但还有其他变化。
您可能希望阅读有关 daylight saving time and time zones 的 Whosebug wiki,以了解这些更改背后的机制。
您也可以尝试我的 Pluralsight 课程 Date and Time Fundamentals,它更详细地解释了这些概念。
另请参阅:What is the difference between DateTime.ToUniversalTime
and TimeZoneInfo.ConvertTimeToUtc
?
在 TimeZoneInfo.ConvertTimeToUtc()
的 MSDN 页面中,有这个信息框:
If the current computer's local time zone includes multiple adjustment rules, this overload of the ConvertTimeToUtc method can return results that differ from the TimeZone.ToUniversalTime and DateTime.ToUniversalTime methods. TimeZone.ToUniversalTime always applies the current adjustment rule to time zone conversion, whether or not dateTime lies within its date range. And when executing on .NET Framework 3.5, DateTime.ToUniversalTime also applies the current adjustment rule to time zone conversion, whether or not dateTime lies within its date range.
我不确定我是否理解这意味着什么。这些调整规则是什么,ConvertTimeToUtc()
和TimeZone.ToUniversalTime()
之间的结果有何不同?
这是一个例子。在撰写本文时,我的计算机 post 设置为美国太平洋时区,今天是 2015 年 3 月 2 日。目前是太平洋标准时间(或 PST),比 UTC 晚 8 小时。
DateTime dt = new DateTime(2006, 4, 1, 0, 0, 0);
TimeZoneInfo tzi = TimeZoneInfo.Local;
DateTime utc = TimeZoneInfo.ConvertTimeToUtc(dt, tzi);
在上面的代码中,我将另一个值(2006 年 4 月 1 日午夜)从我的时区转换为 UTC。在那个特定的时间点,太平洋标准时间(或 PST)生效。上面的代码使用了 TimeZoneInfo
,这是正确的做法。输出是 2006 年 4 月 1 日 8:00 AM UTC。
现在看这段代码:
DateTime dt = new DateTime(2006, 4, 1, 0, 0, 0);
TimeZone tz = TimeZone.CurrentTimeZone;
DateTime utc = tz.ToUniversalTime(dt);
它似乎做几乎相同的事情。但它 returns 7:00 AM UTC 的错误值。
发生这种情况是因为美国 changed it's daylight saving time 规则于 2007 年生效。在示例中的日期,DST 未根据当时的规则生效,但如果当前 规则当时就位。
很简单,TimeZoneInfo
对象知道此更改,但 TimeZone
对象不知道。它错误地假设当前规则始终有效。
TimeZone
class 上的其他方法也会发生同样的事情,这就是为什么 the MSDN reference 说:
Important
Whenever possible, use theTimeZoneInfo
class instead of theTimeZone
class.
此外,TimeZone
class 已从新 .Net CoreCLR 项目中 删除。
关于 "adjustment rules" - MSDN 备注专门指的是 TimeZoneInfo.AdjustmentRule
class,它用于跟踪可能定期或不定期发生的时区偏移变化在一个时区内。夏令时是一种可能发生的变化类型,但还有其他变化。
您可能希望阅读有关 daylight saving time and time zones 的 Whosebug wiki,以了解这些更改背后的机制。
您也可以尝试我的 Pluralsight 课程 Date and Time Fundamentals,它更详细地解释了这些概念。
另请参阅:What is the difference between DateTime.ToUniversalTime
and TimeZoneInfo.ConvertTimeToUtc
?