wom*_*omp 71
没有隐含的时区附加到DateTime
对象.如果运行ToUniversalTime()
它,它将使用运行代码的上下文的时区.
例如,如果我DateTime
从1970年1月1日的时代创建一个,它给了我相同的DateTime
对象,无论我在世界的哪个地方.
如果我ToUniversalTime()
在格林威治运行代码时运行它,那么我会得到相同的时间.如果我在温哥华居住的时候这样做,那么我会得到一个DateTime
-8小时的偏移物体.
这就是为什么在您需要进行任何类型的日期转换或本地化时,将时间相关信息作为UTC时间存储在数据库中的重要性.考虑您的代码库是否已移至另一个时区的服务器设施;)
编辑:来自Joel答案的注释 - DateTime
默认情况下,对象输入为DateTimeKind.Local
.如果您解析日期并将其设置为DateTimeKind.Utc
,则不ToUniversalTime()
执行转换.
这里有一篇关于"使用日期时间编写最佳实践"的文章,以及一篇关于使用.Net转换DateTimes的文章.
Jon*_*eet 34
首先,它会检查是否Kind
的DateTime
被称为是UTC了.如果是,则返回相同的值.
否则,它被假定为本地时间 - 它在运行的计算机的本地时间,特别是在某个私有财产首次被初始化时计算机正在使用的时区.这意味着如果您在应用程序启动后更改时区,则很可能它仍将使用旧时区.
时区包含足够的信息以将本地时间转换为UTC时间,反之亦然,尽管有时候这是不明确的或无效的.(当地时间发生两次,而当地时间由于夏令时而从未发生过.)处理这些情况的规则在文件中规定:
如果日期和时间实例值是不明确的时间,则此方法假定它是标准时间.(模糊时间可以映射到标准时间或本地时区的夏令时)如果日期和时间实例值是无效时间,则此方法只是从本地时区减去本地时间UTC偏移量返回UTC.(由于应用了夏令时调整规则,无效时间是不存在的时间.)
返回的值会产生Kind
的DateTimeKind.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吗?;)