DateTime.ToUniversalTime()如何工作?

der*_*ral 61 .net c# datetime utc

如何从标准DateTime格式转换为UTC ?

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

wom*_*omp 71

没有隐含的时区附加到DateTime对象.如果运行ToUniversalTime()它,它将使用运行代码的上下文的时区.

例如,如果我DateTime从1970年1月1日的时代创建一个,它给了我相同的DateTime对象,无论我在世界的哪个地方.

如果我ToUniversalTime()在格林威治运行代码时运行它,那么我会得到相同的时间.如果我在温哥华居住的时候这样做,那么我会得到一个DateTime-8小时的偏移物体.

这就是为什么在您需要进行任何类型的日期转换或本地化时,将时间相关信息作为UTC时间存储在数据库中的重要性.考虑您的代码库是否已移至另一个时区的服务器设施;)

编辑:来自Joel答案的注释 - DateTime默认情况下,对象输入为DateTimeKind.Local.如果您解析日期并将其设置为DateTimeKind.Utc,则不ToUniversalTime()执行转换.

这里有一篇关于"使用日期时间编写最佳实践"的文章,以及一篇关于使用.Net转换DateTimes的文章.

  • 您不希望*始终*以UTC格式存储与时间相关的信息.这完全取决于信息的真实含义.及时的实例通常可以用UTC表示,但不是一切都是瞬间的.例如,我在帕丁顿乘坐17:18的火车.将它存储为"17:18欧洲/伦敦"而不是"16:18 UTC"是有意义的 - 因为当时钟返回时,*local*时间保持不变. (14认同)
  • "默认情况下,DateTime对象的类型为DateTimeKind.Local".默认为Unspecified(http://msdn.microsoft.com/en-us/library/system.datetime.kind(v=vs.95).aspx) (5认同)
  • 你能说出我在与日历相关的产品上工作吗?;) (3认同)

Jon*_*eet 34

首先,它会检查是否KindDateTime被称为是UTC了.如果是,则返回相同的值.

否则,它被假定为本地时间 - 它在运行的计算机的本地时间,特别是在某个私有财产首次被初始化时计算机正在使用的时区.这意味着如果您应用程序启动更改时区,则很可能它仍将使用旧时区.

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

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

返回的值会产生KindDateTimeKind.Utc,因此,如果调用ToUniveralTime上,它不会再次申请补偿.(这是对.NET 1.1的巨大改进!)

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

基本上.NET 3.5中的支持比它好很多,但仍然需要正确的日历算法.有人想把Joda Time移植到.NET吗?;)

  • 您并不总是想要UTC时间.日期/时间问题非常复杂,*没有"一刀切"的规则.始终使用UTC适用于时间戳,但在其他各种情况下它都很好. (2认同)

Joe*_*orn 7

什么@womp说,增加它检查的DateTime的Kind属性,看它是否可能已经是一个UTC日期.