【问题标题】:Parse Date time with respect to time zone provided in input string根据输入字符串中提供的时区解析日期时间
【发布时间】:2019-05-20 18:31:37
【问题描述】:

我试图理解使用时区信息解析 utc 时间,但我的代码给了我奇怪的结果,或者至少我不理解。

var utcTime = DateTime.Parse("2019-05-20T13:00:00Z", null, System.Globalization.DateTimeStyles.RoundtripKind);
// utcTime = {5/20/2019 1:00:00 PM} (its kind is Utc and this is accepted)

var zonedTime1 = DateTime.Parse("2019-05-20T13:00:00-04:00", null, System.Globalization.DateTimeStyles.RoundtripKind);
//zonedTime1 = {5/20/2019 1:00:00 PM} (its kind is Local, but I was expecting {5/20/2019 9:00:00 AM} with Local kind)

var zonedTime2 = DateTime.Parse("2019-05-20T13:00:00+04:00", null, System.Globalization.DateTimeStyles.RoundtripKind);
//zonedTime2 = {5/20/2019 5:00:00 AM} (its kind is Local, but I was expecting {5/20/2019 5:00:00 PM} with Local kind)

我想知道我哪里错了,或者我的期望哪里错了。如果 utcTime 被正确解析,那么为什么 zonedTime1 和 zonedTime2 会不正确?

【问题讨论】:

  • 您机器的时区是什么,您使用什么来查看这些值? (虽然edit 考虑使用您使用的任何格式添加WriteLine( zonedTime2.ToString(????)),但以“o”开头是个好主意)。
  • 您的结果似乎与您处于 -4 时区一致。我想那是东部时间。

标签: c# datetime utc


【解决方案1】:

ISO 8601 时间戳中的偏移量描述了与 UTC 的偏移量,该偏移量已经在本地时间部分进行了调整。因此:

  • 2019-05-20T13:00:00-04:00 = 2019-05-20T17:00:00Z = 2019-05-20T13:00:00-04:00
  • 2019-05-20T13:00:00+04:00 = 2019-05-20T09:00:00Z = 2019-05-20T05:00:00-04:00

根据您的预期结果,我相信您希望 13:00:00 在所有三种情况下都是 UTC 值,但事实并非如此。

其他几件事:

  • 为区域性传递 null 与传递 CultureInfo.CurrentCulture 相同。您最好将CultureInfo.InvariantCulture 传递给 ISO 8601 时间戳,因为当当前文化使用非公历系统时,它既可以提高性能又可以防止错误。

  • 当解析为DateTime 时,如果输入字符串中存在any 偏移,则结果将调整为本地时区。转换时会考虑原始偏移量,但不会保留。因此,在许多情况下,您最好改用DateTimeOffset 类型。

【讨论】:

  • 感谢@Matt,(+04:00 或 -04:00)显示时区,DateTime.Parse 将其转换回本地时间
  • 它显示了该特定时间点与世界某个时区的 UTC 偏移量。它可能来自本地时区,也可能来自其他时区。此外,该偏移量并不能唯一地标识时区,对于同一时区,它也不总是相同的数字。请参阅the timezone tag wiki 中的“时区!= 偏移量”。但是,是的,DateTime.Parse 会看到偏移量并假设您需要本地时间结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多