从 DateTime 获取时区
Posted
技术标签:
【中文标题】从 DateTime 获取时区【英文标题】:Get timezone from DateTime 【发布时间】:2010-10-09 06:29:42 【问题描述】:.Net DateTime 是否包含有关其创建时区的信息?
我有一个库可以从末尾带有“+zz”的格式解析 DateTime,虽然它可以正确解析并调整本地时间,但我需要从 DateTime 对象中获取特定时区。
这可能吗?我只能看到 DateTime.Kind,它指定时间是本地时间还是 UTC。
【问题讨论】:
请参阅DateTime.Parse documentation 上的注释,了解时区和日期时间样式的处理。但是不,你想要的实际上是不可能的。 【参考方案1】:DateTime 不知道其时区偏移量。没有内置方法可以返回偏移量或时区名称(例如 EAT、CEST、EST 等)。
按照其他人的建议,您可以将日期转换为 UTC:
DateTime localtime = new DateTime.Now;
var utctime = localtime.ToUniversalTime();
然后只计算差值:
TimeSpan difference = localtime - utctime;
您也可以使用 DateTimeOffset 将一个时间转换为另一个时间:
DateTimeOffset targetTime = DateTimeOffset.Now.ToOffset(new TimeSpan(5, 30, 0));
但这是一种有损压缩 - 仅偏移量无法告诉您它所在的时区,因为两个不同的国家可能位于不同的时区,并且仅在一年中的部分时间具有相同的时间(例如,南非和欧洲)。此外,请注意,夏季夏令时可能会在不同的日期引入(EST 与 CET - 3 周的差异)。
您可以使用 TimeZoneInfo 类获取本地系统时区的名称:
TimeZoneInfo localZone = TimeZoneInfo.Local;
localZone.IsDaylightSavingTime(localtime) ? localZone.DaylightName : localZone.StandardName
我同意 Gerrie Schenck 的观点,请阅读他建议的文章。
【讨论】:
【参考方案2】:通常的做法是将数据作为具有 UTC“时区”的 DateTime 传递,然后传递 TimeZoneInfo 对象,当您准备好显示数据时,使用 TimeZoneInfo 对象转换 UTC DateTime。
另一个选项是使用当前时区设置 DateTime,然后确保 DateTime 对象的“时区”未知,然后确保再次传递 DateTime,并使用指示传递的 DateTime 的 TimeZone 的 TimeZoneInfo .
正如其他人在这里指出的那样,如果 Microsoft 能够在此基础上创建一个很好的对象来完成这一切,那就太好了,但现在您必须处理两个对象。
【讨论】:
【参考方案3】:DateTime 本身不包含实际时区信息。它可能知道它是 UTC 还是本地,但不知道本地的真正含义。
DateTimeOffset 稍微好一些 - 这基本上是 UTC 时间和偏移量。但是,这仍然不足以确定时区,因为许多不同的时区在任何一个时间点都可以具有相同的偏移量。不过,这听起来对您来说可能已经足够好了,因为在解析日期/时间时您所要做的就是偏移量。
.NET 3.5 对时区的支持比以前好很多,但我真的很想看到标准的“ZonedDateTime”或类似的东西——UTC 时间和实际时区。自己构建很容易,但如果能在标准库中看到它会很高兴。
编辑:将近四年后,我现在建议使用Noda Time,它有一组相当丰富的日期/时间类型。不过,作为野田时间的主要作者,我有偏见:)
【讨论】:
CodePlex 上的 PublicDomain 项目会为您完成这项工作。 如果世界时区是静态的并且不会改变,BCL 中的 TimeZone 枚举会很好。 @jlafay:但是,它们确实发生了变化——例如,就在去年,Windows 中添加了更多时区。 此项目不再由作者维护; publicdomain.codeplex.com 好像这个可能有帮助,根据使用情况,使用前必须设置它; timezone.codeplex.com @AnneTheAgile:我个人推荐使用我自己的 Noda Time 库,当然 :)【参考方案4】:您可以使用 TimeZoneInfo 类
TimeZone 类识别本地时区,并且可以在协调世界时 (UTC) 和本地时间之间转换时间。 TimeZoneInfo 对象可以表示任何时区,TimeZoneInfo 类的方法可用于将一个时区的时间转换为任何其他时区的对应时间。 TimeZoneInfo 类的成员支持以下操作:
检索已由操作员定义的时区 系统。
枚举系统上可用的时区。
不同时区之间的时间转换。
创建一个尚未由 操作系统。
序列化时区以供以后检索。
【讨论】:
...但是,据我所知,给定一个 DateTime,仍然没有办法使用 TimeZoneInfo 来确定 DateTime 的 TimeZone。 @RemiDespres-Smyth 我只是将 TimeZoneInfo 和 DateTime 一起存储在 1 个类中。【参考方案5】:有一个public domain TimeZone library for .NET。真的很有用。它将满足您的需求。
解决一般情况下的时区问题比您想象的要难。
【讨论】:
【参考方案6】:从 API (http://msdn.microsoft.com/en-us/library/system.datetime_members(VS.71).aspx) 看来,它似乎无法显示所用时区的名称。
【讨论】:
【参考方案7】:没有。
开发人员负责通过某种外部机制跟踪与 DateTime 值关联的时区信息。
引用一篇优秀文章here。 每个 .Net 开发人员都必须阅读。
所以我的建议是编写一个适合您需求的小包装类。
【讨论】:
这篇文章可以总结为:“.NET中的DateTime有bug和不足,你处理一下。”以上是关于从 DateTime 获取时区的主要内容,如果未能解决你的问题,请参考以下文章
如何在忽略时区问题的情况下从 SQL Server 获取 DateTime 数据?
将 Postgres 中没有时区的 DateTime 字段从中欧时间转换为 UTC
Python 调用datetime或者time获取时间的时候以及时间转换,最好设置一下时区 否则会出现相差8个小时的情况