我在理解如何正确地将DateTime
转换为不同的时区时遇到问题。
让我们说,我想转换DateTime
的时间:美国东部时间10:00(军事)到UTC的DateTime
。
这是我尝试的:
DateTime unspecified = new DateTime(2013, 8, 15, 10, 0, 0, DateTimeKind.Unspecified);
var utc = TimeZoneInfo.ConvertTime(unspecified, TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time"), TimeZoneInfo.Utc);
...我用DateTime
构建DateTimeKind.Unspecified
,因为它既不是UTC,也不是当地时间(美国东部时间10点)。然后我将它传递给TimeZoneInfo.ConvertTime,告诉我这是EST中的DateTime
,我想将其转换为UTC。
因为EST is 5 hours behind of Coordinated Universal Time (UTC)我希望utc
等于{15.08.2013 15:00:00}
,但是当我在上面运行代码时,由于某种原因,得到{15.08.2013 14:00:00}
(即时差为4小时)。
问题是:为什么?这是某种白天节约时间吗?如果是这样 - 如何在没有白天节省时间的情况下进行此转换?
是的,应用了夏令时。见qazxsw poi
在观察标准时间(秋/冬)时使用东部标准时间(EST)的地方比协调世界时(UTC-05:00)落后5小时。
东部夏令时(EDT),当观察夏令时(春/夏)时,比协调世界时(UTC-04:00)落后4小时。
转换方法是正确的。你对EST时区的假设是有缺陷的。如果您的输入日期确实是EST,那么转换是正确的。如果这不符合您的期望,您需要检查输入数据的来源以及输入的时区。如果您正在处理数据库中保存的日期,并且您不知道什么是正确的,哪些不是您遇到麻烦。
通常,使用Wikipedia而不是DateTime更安全,因为它确实将UTC时间作为DateTime存储,并将本地时区偏移作为其中的附加值存储。这使得从当地时间确定真实的UTC时间变得微不足道。
拥有DateTimeOffset的Id
的Windows时区不仅适用于EST。它涵盖EST(-5)和EDT(-4)。你不会仅仅从id名称知道它。这有点命名异常是Microsoft Windows时区数据库的几个棘手问题之一。有关更多信息,请参阅"Eastern Standard Time"
。
幸运的是,它不是唯一的数据库。它甚至不是最常用的数据库,它只是Windows和.Net附带的默认数据库。要使用标准IANA时区数据库执行此转换,请使用the timezone tag wiki:
Noda Time
另请注意Noda Time如何为您提供无法解释的类型。没有影响行为的DateTimeZone tz = DateTimeZoneProviders.Tzdb["America/New_York"];
LocalDateTime dt = new LocalDateTime(2013, 8, 15, 10, 0, 0);
ZonedDateTime zdt = tz.AtLeniently(dt);
Instant utc = zdt.ToInstant();
。这里的“本地”只是意味着一些本地价值,而不是你自己的本地时钟。
另请注意,我使用Kind
将日期应用于时区。这是一种在应用模糊或无效时间时进行调整的策略。还有AtLeniently
,它将在这些场景中抛出异常。或者,您可以创建自己的策略。 AtStrictly
类没有这种控制水平。