DateTime.ToUniversalTime()如何工作?

从标准DateTime格式转换到UTC如何工作?

更具体地说,如果我在一个时区中创build一个DateTime对象,然后切换到另一个时区并运行ToUniversalTime() ,它如何知道转换是否正确完成,时间仍然准确表示?

DateTime对象没有附加的隐式时区。 如果你运行ToUniversalTime() ,它使用运行代码的上下文的时区。

例如,如果我从1970年1月1日创buildDateTime ,那么无论我在世界的什么地方,它都会给我相同的DateTime对象。

如果我在格林威治运行代码时运行ToUniversalTime() ,那么我可以得到同样的时间。 如果我住在温哥华的话,我会得到一个-8小时的抵消DateTime对象。

这就是为什么当您需要进行任何types的date转换或本地化时,将时间相关的信息存储在数据库中的时间很重要。 考虑你的代码库是否被移到了另一个时区的服务器设施中;)

编辑:注意Joel的答案 – 默认DateTime对象被键入为DateTimeKind.Local 。 如果parsingdate并将其设置为DateTimeKind.Utc ,则ToUniversalTime()执行转换。

这里有一篇关于“使用date时间编码的最佳实践”的文章,以及一篇关于使用.Net转换 date时间的文章。

首先,它检查DateTimeKind是否已经是UTC。 如果是这样,它返回相同的值。

否则,它被认为是当地时间 – 对于正在运行的计算机而言是当地时间,特别是当一些私有财产首次被懒惰地初始化时计算机正在使用的时区。 这意味着,如果您应用程序启动更改时区,则很可能仍会使用旧时区。

时区包含足够的信息来将本地时间转换为UTC时间,反之亦然,但有时候这是不明确的或无效的。 (当地时间有两次发生,当地时间由于夏令时而不发生)。处理这些案件的规则在文件中有规定:

如果date和时间实例值是模糊的时间,则此方法假定它是标准时间。 (模糊时间可以映射到本地时区的标准时间或夏令时)如果date和时间实例值是无效时间,则此方法仅从本地时区的当地时间减去UTC偏移量返回UTC。 (由于应用了夏令时调整规则,无效时间是不存在的时间。)

返回的值将有Kind DateTimeKind.Utc ,所以如果您调用ToUniveralTime ,它将不会再次应用该偏移量。 (这是对.NET 1.1的巨大改进!)

如果你想要一个非本地的时区,你应该使用在.NET 3.5中引入的TimeZoneInfo (早期版本有一些黑客解决scheme,但不是很好)。 为了及时表示,您应该考虑使用.NET 2.0SP1,.NET3.0SP1和.NET 3.5中引入的DateTimeOffset 。 然而,这还没有一个实际的时区与它相关 – 只是从UTC的偏移量。 这意味着你不知道当地时间将在一个小时之后,例如,DST规则可能会在不同时区之间发生变化,而这些时区恰好在特定时刻使用相同的偏移量。 TimeZoneInfo旨在考虑历史和未来的规则,而TimeZone则相当简单。

基本上.NET 3.5中的支持比现在好得多,但是仍然需要适当的日历算术。 任何人都喜欢将Joda Time移植到.NET? ;)

@womp说什么,除此之外,它检查DateTime的Kind属性,看它是否可能已经是UTCdate。

DateTime.ToUniversalTime删除本地时区的时区偏移量以将DateTime标准化为UTC。 如果对其他时区中的规范化值使用DateTime.ToLocalTime,则该时区的时区偏移量将被添加到该时区中正确表示的规范化值。