正在将DateTime从特定时区转换为UTC-缺少小时



我在理解如何将DateTime正确转换为不同时区时遇到问题。

比方说,我想将时间为美国东部时间10:00(军用)的DateTime转换为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);

我用DateTimeKind.Unspecified构造DateTime,因为它既不是UTC,也不是当地时间(现在是美国东部时间10:00)。然后我把它传给TimeZoneInfo.ConvertTime,告诉它这是EST中的DateTime,我想把它转换成UTC。

由于EST比协调世界时(UTC)晚了5小时,我希望utc等于{15.08.2013 15:00:00},但当我运行高于I的代码时,由于某种原因,会得到{15.08.2013 14:00:00}(即时差4小时

问题是:为什么?这是为了节省白天的时间吗?如果是这样的话,如何在没有白天节省时间的情况下进行转换?

具有"Eastern Standard Time"Id的Windows时区不仅仅用于EST。它包括EST(-5)和EDT(-4)。单从身份证的名字你是不会知道的。这有点命名异常,这是微软Windows时区数据库的几个奇怪之处之一。有关详细信息,请参阅时区标记wiki。

幸运的是,它并不是唯一的数据库。它甚至不是最常用的数据库,它只是Windows和.Net附带的默认数据库。要使用标准IANA时区数据库进行转换,请使用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();

还要注意Noda Time是如何为您提供无法误解的类型的。没有影响行为的Kind。这里的"本地"只是指一些本地值,而不是您自己的本地时钟。

还要注意,我使用AtLeniently将日期应用于时区。这是一种在应用模糊或无效时间时进行调整的策略。还有AtStrictly,它将在这些场景中抛出异常。或者,你可以制定自己的策略。TimeZoneInfo类没有这种级别的控制。

是的,应用了dalylight保存。参见维基百科

遵守标准时使用东部标准时间(EST)的地方时间(秋季/冬季)比协调世界时晚5小时(UTC−05:00)。

东部夏令时(EDT),当观测夏令时时(春季/夏季)比协调世界时晚4小时(UTC−04:00)。

转换方法正确。你对美国东部时间的假设是有缺陷的。如果您输入的日期确实是EST,那么转换是正确的。如果这不符合您的期望,您需要检查输入数据的来源以及实际输入的时区。如果你正在处理数据库中保存的日期,而你再也不知道什么是正确的,什么不是,你就有麻烦了。

一般来说,使用DateTimeOffset而不是DateTime更安全,因为它总是将UTC时间存储为DateTime,并将本地时区偏移量存储为其内部的附加值。这使得从本地时间确定真正的UTC时间变得微不足道。

您可以轻松地将任何时区的任何DateTime转换为UTCDateTime。

以下是示例

   string DisplayName = "custom standard name here";
   string StandardName = "custom standard name here"; 
   string YourDate="2013/8/15 10:0:0"; 
   TimeSpan Offset = new TimeSpan(+10, 00, 00);
   TimeZoneInfo TimeZone = TimeZoneInfo.CreateCustomTimeZone(StandardName, Offset, DisplayName, StandardName);
   var RawDateTime = DateTime.SpecifyKind(DateTime.Parse(YourDate), DateTimeKind.Unspecified);
   DateTime UTCDateTime = TimeZoneInfo.ConvertTimeToUtc(RawDateTime, TimeZone);
   Console.WriteLine(UTCDateTime);

相关内容

  • 没有找到相关文章

最新更新