Get timezone from DateTime

Does the .Net DateTime contain information about time zone where it was created?

I have a library parsing DateTime from a format that has "+zz" at the end, and while it parses correctly and adjusts a local time, I need to get what the specific time zone was from the DateTime object.

Is this possible at all? All I can see is DateTime.Kind, which specifies if time is local or UTC.

131682 次浏览

No.

A developer is responsible for keeping track of time-zone information associated with a DateTime value via some external mechanism.

引自一篇优秀的文章 给你。 A must read for every .Net developer.

所以我的建议是编写一个适合您需要的小包装类。

从 API (http://msdn.microsoft.com/en-us/library/system.datetime_members(VS.71).aspx)看,它似乎不能显示所使用的时区的名称。

DateTime 本身不包含实际的时区信息。它 知道它是 UTC 还是 local,但不知道 local 的真正含义。

DateTimeOffset 稍好一些——它基本上是一个 UTC 时间和一个偏移量。然而,这仍然不足以确定时区,因为许多不同的时区可以在任何一个时间点有相同的偏移量。不过,这听起来似乎对您来说已经足够好了,因为在解析日期/时间时,您需要处理的只是偏移量。

对时区的支持。NET 3.5比以前好多了,但我真的很想看到一个标准的“ ZonedDateTime”或类似的东西——一个 UTC 时间和一个实际的时区。构建自己的库很容易,但是如果能在标准库中看到它就更好了。

编辑: 将近四年后,我现在建议使用 Noda Time,它具有更丰富的日期/时间类型。不过,作为《野田时代》(Noda Time)的主要作者,我有偏见。)

There is a 用于.NET 的公共域 TimeZone 库. Really useful. It will answer your needs.

解决一般情况下的时区问题比你想象的要难。

You could use 时区信息 class

TimeZone 类识别本地时区,并可以在协调世界时(UTC)和本地时间之间转换时间。TimeZoneInfo 对象可以表示任何时区,TimeZoneInfo 类的方法可以用于将一个时区中的时间转换为任何其他时区中的相应时间。TimeZoneInfo 类的成员支持以下操作:

  1. 检索已由操作定义的时区 系统

  2. 枚举系统上可用的时区。

  3. 在不同时区之间转换时间。

  4. 方法尚未定义的新时区 operating system.

    序列化时区以便以后检索。

通常的做法是将数据作为具有 UTC“时区”的 DateTime 传递,然后传递一个 TimeZoneInfo 对象,当准备显示数据时,使用 TimeZoneInfo 对象转换 UTC DateTime。

另一个选项是使用当前时区设置 DateTime,然后确保 DateTime 对象的“ TimeZone”是未知的,然后确保再次使用 TimeZoneInfo 传递 DateTime,该 TimeZoneInfo 指示传递的 DateTime 的 TimeZone。

As others have indicated here, it would be nice if Microsoft got on top of this and created one nice object to do it all, but for now you have to deal with two objects.

日期时间不知道其时区偏移量。没有返回偏移量或时区名称的内置方法(如 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));

但是这是一种有损数据压缩——单靠偏移量不能告诉你是哪个时区,因为两个不同的国家可能处于不同的时区,而且一年中只有部分时间是相同的(例如:。南非和欧洲)。此外,要注意夏季夏时制可能会在不同的日期推出(美国东部夏令时和英国中部夏令时相差3周)。

您可以使用 TimeZoneInfo 类获取本地系统时区的名称:

TimeZoneInfo localZone = TimeZoneInfo.Local;
localZone.IsDaylightSavingTime(localtime) ? localZone.DaylightName : localZone.StandardName

我同意 Gerrie Schenck 的观点,请读一下他建议的文章。