.Net DateTime 是否包含有关其创建时区的信息?
我有一个库从末尾有“+zz”的格式解析 DateTime,虽然它可以正确解析并调整本地时间,但我需要从 DateTime 对象中获取特定时区。
这可能吗?我只能看到 DateTime.Kind,它指定时间是本地时间还是 UTC。
DateTime 本身不包含真正的时区信息。它可能知道它是 UTC 还是本地,但不知道本地的真正含义。
DateTimeOffset 稍微好一些 - 这基本上是 UTC 时间和偏移量。但是,这仍然不足以确定时区,因为许多不同的时区在任何一个时间点都可以具有相同的偏移量。不过,这听起来对您来说可能已经足够好了,因为在解析日期/时间时您所要做的就是偏移量。
.NET 3.5 对时区的支持比以前好很多,但我真的很想看到标准的“ZonedDateTime”或类似的东西——UTC 时间和实际时区。构建你自己的很容易,但是在标准库中看到它会很高兴。
编辑:将近四年后,我现在建议使用具有更丰富的日期/时间类型集的Noda Time 。不过,作为野田时间的主要作者,我有偏见:)
.NET有一个公共领域的 TimeZone 库。真的很有用。它将满足您的需求。
解决一般情况下的时区问题比您想象的要难。
您可以使用TimeZoneInfo类
TimeZone 类识别本地时区,并且可以在协调世界时 (UTC) 和本地时间之间转换时间。TimeZoneInfo 对象可以表示任何时区,TimeZoneInfo 类的方法可以将一个时区的时间转换为任何其他时区的对应时间。TimeZoneInfo 类的成员支持以下操作:
检索已由操作系统定义的时区。
枚举系统上可用的时区。
在不同时区之间转换时间。
创建操作系统尚未定义的新时区。
序列化时区以供以后检索。
从 API(http://msdn.microsoft.com/en-us/library/system.datetime_members(VS.71).aspx)看来,它似乎无法显示所用时区的名称。
通常的做法是将数据作为带有 UTC“时区”的 DateTime 传递,然后传递一个 TimeZoneInfo 对象,当您准备好显示数据时,使用 TimeZoneInfo 对象转换 UTC DateTime。
另一个选项是使用当前时区设置 DateTime,然后确保 DateTime 对象的“时区”是未知的,然后确保再次传递 DateTime,并使用指示传递的 DateTime 的 TimeZone 的 TimeZoneInfo。
正如其他人在这里指出的那样,如果 Microsoft 能够在此基础上创建一个很好的对象来完成这一切,那就太好了,但是现在您必须处理两个对象。
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 的观点,请阅读他建议的文章。