从DateTime获取时区


103

.Net DateTime是否包含有关在其创建时区的信息?

我有一个库,它以末尾带有“ + zz”的格式解析DateTime,尽管它可以正确解析并调整本地时间,但我需要从DateTime对象中获取特定的时区。

这有可能吗?我只能看到DateTime.Kind,它指定时间是本地时间还是UTC。


请参阅有关DateTime.Parse文档的注释,以了解时区和DateTimeStyles。但是,不,您真正想要的是不可能的。
yoyo

Answers:


136

DateTime本身不包含任何实时时区信息。它可能知道它是UTC还是本地的,但不知道本地的真正含义。

DateTimeOffset更好一些-基本上是UTC时间和偏移量。但是,这仍然不足以确定时区,因为许多不同的时区在任何一个时间点都可以具有相同的偏移量。听起来这可能对您来说已经足够了,因为解析日期/时间时要做的就是偏移。

从.NET 3.5开始,对时区的支持要好得多,但是我真的很想看到一个标准的“ ZonedDateTime”或类似的东西-UTC时间和实际时区。自己构建很容易,但是很高兴在标准库中看到它。

编辑:近四年后,我现在建议使用Noda Time,它具有一组比较丰富的日期/时间类型。不过,我还是有偏见,作为Noda Time的主要作者:)


2
CodePlex上的PublicDomain项目可以为您完成此任务。
Cheeso

如果世界时区是静态的并且没有变化,则BCL中的TimeZone枚举会很好。
杰夫·拉法

1
@jlafay:但是,它们的确发生了变化-例如,仅在去年Windows上添加了更多时区。
乔恩·斯基特

该项目不再由作者维护; publicdomain.codeplex.com 似乎这可能会有所帮助,具体取决于用法,一个人必须在使用前进行设置;timezone.codeplex.com
AnneTheAgile 2013年

3
@AnneTheAgile:我个人当然建议使用自己的Noda Time库:)
Jon Skeet 2013年

36

没有。

开发人员负责通过某种外部机制跟踪与DateTime值关联的时区信息。

引用这里一篇出色的文章。每个.Net开发人员都必须阅读。

因此,我的建议是编写一个适合您需求的包装器类。



2

您可以使用TimeZoneInfo

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

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

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

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

  4. 创建操作系统尚未定义的新时区。

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


1
...但是,据我所知,给定一个DateTime,仍然无法使用TimeZoneInfo确定DateTime的TimeZone。
Remi Despres-Smyth

@ RemiDespres-Smyth我只将TimeZoneInfo和DateTime一起存储在1类中。
康拉德


0

通常,惯例是将数据作为带有UTC的“时区”的DateTime传递,然后传递TimeZoneInfo对象,当准备显示数据时,可以使用TimeZoneInfo对象转换UTC DateTime。

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

正如其他人在这里指出的那样,如果Microsoft掌握了这一点并创建了一个不错的对象来完成所有工作,那将是很好的选择,但是现在您必须处理两个对象。


0

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的观点,请阅读他建议的文章。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.