【问题标题】:UTC DateTime Conversion To US EasternUTC 日期时间转换为美国东部时间
【发布时间】:2017-09-11 11:10:13
【问题描述】:

我对 UTC 感到困惑,在任何地方都找不到任何东西。

我的格林威治标准时间是 00:00:00

我想将其转换为美国东部标准时间的 UTC 时间。

我得到 04:00:00-04 作为 UTC 字符串。

这是我的代码。

string UTCDateTime;
TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById("US Eastern Standard Time")
DateTime dateTimeOld = new DateTime(2017,09,11,0,0,0);
DateTime dateTime = TimeZoneInfo.ConvertTimeToUtc(dateTimeOld, timeZone);

UTCDateTime = dateTime.ToUniversalTime().ToString("yyyy-MM-dd HH:mm:ss");

var offset = timeZone.GetUtcOffset(dateTime);

UTCDateTime += ((offset < TimeSpan.Zero) ? "-" : "+") + offset.ToString("hh");'

所以我的输出将是一个 UTC 字符串:“2017-09-11 04:00:00-04”。

正确吗?不应该是“2017-09-11 00:00:00-04”

【问题讨论】:

  • 您的问题令人困惑。您了解 UTC、GMT 和 EST 之间的区别吗?我保证有大量关于时区的文档。
  • UTC 是格林威治标准时间。东部标准时间是 UTC 的 -5。因此,当 UTC 为 00:00 EST 时为 7:00PM(夏令时:DST 8:00PM)。看起来你正在向后转换。 00:00 EDT 是 04:00 UTC
  • @jdweng 所以输出应该是“2017-09-11 00:00:00-04”,其中-4是时区。
  • @Equalsk 你能指出我正确的方向吗?我在问,UTC 字符串是否应该是“2017-09-11 04:00:00-04”。或“2017-09-11 00:00:00-04”为美国东部时间当地时间上午 12:00
  • @Sam 我想你错过了TimeZoneInfo.ConvertTimeToUtc 的工作原理。由于您的dateTimeOld 具有Unspecified 作为Kind 属性,因此此方法假定它是 时区的标准时间,在我们的例子中是美国东部标准时间。由于 this 时区比 UTC 晚 4 小时,因此当您将此时区中的日期时间转换为 UTC 时,最终将添加 4 小时。此外,由于您的dateTime 已经是Utc,您的ToUniversalTime 确实执行任何对话。最好检查两次你想要做什么以及你的代码真正做什么。

标签: c# .net datetime timezone


【解决方案1】:

DateTimeOffset 可以更好地处理此用例。

// The source time in UTC
DateTimeOffset utc = new DateTimeOffset(2017, 9, 11, 0, 0, 0, TimeSpan.Zero);

// The time zone for the Eastern US
TimeZoneInfo timeZone = TimeZoneInfo.FindSystemTimeZoneById("Eastern Standard Time");

// The converted time in the time zone
DateTimeOffset eastern = TimeZoneInfo.ConvertTime(utc, timeZone);

// output in a usable format
Console.WriteLine(eastern.ToString("yyyy-MM-dd HH:mm:ss zzz"));

//=>  2017-09-10 20:00:00 -04:00

几点说明:

  • 在这种情况下,GMT 和 UTC 的含义相同。说你有 GMT 并且你想要 UTC 是荒谬的。如果您指的是特定格式的字符串,请描述该格式。 UTC 不是字符串格式。

  • "US Eastern Standard Time" 条目只能在印第安纳州的某些地区使用。大多数美国东部时区由"Eastern Standard Time" 条目表示。如果您有兴趣,请参阅Time in Indiana 了解更多详情。

  • 不要假设所有时区都只有小时偏移。许多还抵消了 30 或 45 分钟。如果您使用这些时区中的任何一个,只显示小时可能会导致数据错误。

  • 避免调用ToUniversalTime,除非源数据确实在计算机的本地时区中。

  • 注意输出。您的代码或您的假设都不正确。美国东部比世界标准时间四个小时。因此,如果是 UTC 午夜,则为美国东部时间前一天的 20:00(或晚上 8:00)。

【讨论】:

    【解决方案2】:

    您的 dateTimeOld 是美国东部标准时间的午夜。

    然后您使用您的时区将其转换为 UTC 并输入 dateTime。

    由于 UTC 比美国东部标准时间早 4 小时,这意味着使用 DateTimeKind.Utc 的日期时间现在是 04:00。

    然后在分配中再次将其转换为 UTCDateTime。但由于它已经是 UTC(来自您之前的转换),所以它什么也不做。所以它会将 2017-09-11 04:00:00 放入字符串 UTCDateTime。

    然后,您从您的时区信息中添加时区偏移量 - 这没有任何意义。 时区与本地时间相关联,即 dateTimeOld。通过转换为 UTC,您可以特别摆脱时区偏移。

    所以要么从 dateTimeOld 初始化字符串并添加时区偏移量 - 这将给出: 2017-09-11 00:00:00-04

    或者直接使用 dateTime 中的 UTC 时间和一个 'Z' 后缀来表示 UTC(祖鲁时间),这样你就得到了 2017-09-11 04:00:00Z

    这两个都表示相同的时间(除非我复制粘贴的东西有误):)

    一般来说,在处理日期时,常见的约定是尽快将数据转换为 UTC,并在整个程序中保持 UTC - 然后在显示数据时转换为本地时间。但您也可以选择使用 DateTimeOffset - 与 DateTime 不同,它可以跨多个时区存储本地时间。

    【讨论】:

      猜你喜欢
      • 2016-05-25
      • 2021-09-30
      • 2022-06-29
      • 2015-09-24
      • 1970-01-01
      • 2016-05-24
      • 1970-01-01
      • 2011-08-25
      • 2014-04-01
      相关资源
      最近更新 更多