C# DateTime.ToUniversalTime() 如何工作?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1201378/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-06 10:45:17  来源:igfitidea点击:

How does DateTime.ToUniversalTime() work?

c#.netdatetimeutc

提问by derGral

How does the conversion to UTC from the standard DateTimeformat work?

从标准DateTime格式转换为 UTC 是如何工作的?

More specifically, if I create a DateTimeobject in one time zone and then switch to another time zone and run ToUniversalTime()on it, how does it know the conversion was done correctly and that the time is still accurately represented?

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

采纳答案by womp

There is no implicit timezone attached to a DateTimeobject. If you run ToUniversalTime()on it, it uses the timezone of the context that the code is running in.

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

For example, if I create a DateTimefrom the epoch of 1/1/1970, it gives me the same DateTimeobject no matter where in the world I am.

例如,如果我DateTime从 1970 年 1 月 1 日的纪元创建一个,那么DateTime无论我在世界的哪个地方,它都会为我提供相同的对象。

If I run ToUniversalTime()on it when I'm running the code in Greenwich, then I get the same time. If I do it while I live in Vancouver, then I get an offset DateTimeobject of -8 hours.

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

This is why it's important to store time related information in your database as UTC times when you need to do any kind of date conversion or localization. Consider if your codebase got moved to a server facility in another timezone ;)

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

Edit: note from Joel's answer - DateTimeobjects by default are typed as DateTimeKind.Local. If you parse a date and set it as DateTimeKind.Utc, then ToUniversalTime()performs no conversion.

编辑:Joel 的回答中的注释 -DateTime默认情况下,对象的类型为DateTimeKind.Local. 如果您解析日期并将其设置为DateTimeKind.Utc,则不ToUniversalTime()执行任何转换。

And here's an article on "Best Practices Coding with Date Times", and an article on Converting DateTimes with .Net.

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

回答by Joel Coehoorn

What @womp said, with the addition that it checks the DateTime's Kind property to see if it might alreadybe a UTC date.

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

回答by Michael A. McCloskey

DateTime.ToUniversalTime removes the timezone offset of the local timezone to normalize a DateTime to UTC. If you then use DateTime.ToLocalTime on the normalized value in another timezone, the timezone offset of that timezone will be added to the normalized value for correct representation in that timezone.

DateTime.ToUniversalTime 删除本地时区的时区偏移量以将 DateTime 规范化为 UTC。如果您随后对另一个时区中的规范化值使用 DateTime.ToLocalTime,则该时区的时区偏移量将添加到规范化值中,以便在该时区中正确表示。

回答by Jon Skeet

Firstly, it checks whether the Kindof the DateTimeis known to be UTC already. If so, it returns the same value.

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

Otherwise, it's assumed to be a local time - that's local to the computer it's running on, and in particular in the time zone that the computer was using when some private property was first lazily initialized. That means if you change the time zone afteryour application was started, there's a good chance it will still be using the old one.

否则,它被假定为本地时间——它是运行它的计算机的本地时间,特别是在某些私有属性第一次延迟初始化时计算机使用的时区。这意味着如果您应用程序启动更改时区,它很有可能仍会使用旧时区。

The time zone contains enough information to convert a local time to a UTC time or vice versa, although there are times that that's ambiguous or invalid. (There are local times which occur twice, and local times which never occur due to daylight saving time.) The rules for handling these cases are specified in the documentation:

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

If the date and time instance value is an ambiguous time, this method assumes that it is a standard time. (An ambiguous time is one that can map either to a standard time or to a daylight saving time in the local time zone) If the date and time instance value is an invalid time, this method simply subtracts the local time from the local time zone's UTC offset to return UTC. (An invalid time is one that does not exist because of the application of daylight saving time adjustment rules.)

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

The returned value will have a Kindof DateTimeKind.Utc, so if you call ToUniveralTimeon that it won't apply the offset again. (This is a vast improvement over .NET 1.1!)

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

If you want a non-local time zone, you should use TimeZoneInfowhich was introduced in .NET 3.5 (there are hacky solutions for earlier versions, but they're not nice). To represent an instant in time, you should consider using DateTimeOffsetwhich was introduced in .NET 2.0SP1, .NET3.0SP1 and .NET 3.5. However, that still doesn't have an actual time zone associated with it - just an offset from UTC. That means you don't know what local time will be one hour later, for example - the DST rules can vary between time zones which happened to use the same offset for that particular instant. TimeZoneInfois designed to take historical and future rules into account, as opposed to TimeZonewhich is somewhat simplistic.

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

Basically the support in .NET 3.5 is a lot better than it was, but still leaves something to be desired for proper calendar arithmetic. Anyone fancy porting Joda Timeto .NET? ;)

基本上 .NET 3.5 中的支持比以前好很多,但对于正确的日历算法仍然有一些不足之处。有人喜欢将Joda Time移植到 .NET 吗?;)