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
How does DateTime.ToUniversalTime() work?
提问by derGral
How does the conversion to UTC from the standard DateTime
format work?
从标准DateTime
格式转换为 UTC 是如何工作的?
More specifically, if I create a DateTime
object 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 DateTime
object. 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 DateTime
from the epoch of 1/1/1970, it gives me the same DateTime
object 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 DateTime
object 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 - DateTime
objects 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 Kind
of the DateTime
is known to be UTC already. If so, it returns the same value.
首先,它会检查是否Kind
的DateTime
被称为是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 Kind
of DateTimeKind.Utc
, so if you call ToUniveralTime
on that it won't apply the offset again. (This is a vast improvement over .NET 1.1!)
返回的值将有一个Kind
of DateTimeKind.Utc
,因此如果您调用ToUniveralTime
它,它将不会再次应用偏移量。(这是对 .NET 1.1 的巨大改进!)
If you want a non-local time zone, you should use TimeZoneInfo
which 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 DateTimeOffset
which 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. TimeZoneInfo
is designed to take historical and future rules into account, as opposed to TimeZone
which 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 吗?;)