获取C#以正确设置已解析的ISO 8601字符串的Kind属性

时间:2018-12-01 01:33:32

标签: c# datetime iso

我正在努力理解为什么解析由DateTime的Parse方法解析的ISO 8601格式的字符串不会设置新Kind对象的DateTime属性的原因正确地。我查看了帖子How to create a .NET DateTime from ISO 8601 format,并与ISO文档结合使用,看来Parse方法应该能够设置Kind值,但是不能。

示例:

Console.Write(System.DateTime.Parse("2018-11-17T01:00:00").Kind);

返回:未指定

但是,根据ISO标准,这是一种有效的格式,表明该值是本地时间。

Time Zone Section

  

ISO 8601中的时区表示为本地时间(未指定位置),UTC或与UTC的偏移量。如果未使用时间表示形式提供任何UTC关系信息,则该时间假定为当地时间。

Coordinated Universal Time (UTC)

  

如果时间以UTC表示,则在时间后直接添加一个Z,不能带空格。 Z是UTC偏移为零的区域指示符

甚至陌生的是,在字符串中添加Z会将Kind属性设置为Local。

为了正确设置UTC字符串的Kind值,在Parse方法中需要RoundtripKind的DateTimeStyle。但是,如果再次从字符串Kind中删除Z,则会再次设置为Unspecified。

DateTime类是否有问题?

Microsoft是否未遵循ISO标准?

还是我不了解ISO标准?

3 个答案:

答案 0 :(得分:2)

要解析ISO 8601字符串并适当设置DateTimeKind,可以将DateTimeStyles.RoundtripKindthe o standard format specifier或包含the K custom format specifier的自定义字符串一起使用。

例如:

DateTime dt = DateTime.ParseExact(yourISO8601String, "yyyy-MM-dd'T'HH:mm:ss.FFFK",
                                CultureInfo.InvariantCulture, DateTimeStyles.RountripKind);

DateTimeStyles.RoundtripKind提供以下行为:

  • 如果传入的值未提供时区偏移,则生成的DateTime将具有DateTimeKind.Unspecified
  • 如果传入值的时区偏移为Z,则生成的DateTime将具有DateTimeKind.Utc
  • 如果传入的值具有时区偏移量,例如-07:00+01:00甚至是+00:00,则生成的DateTime将具有DateTimeKind.Local ,该值将从提供给本地时区的时区偏移量转换。

尽管这在许多情况下都有效,但通常不希望使用第三个项目符号的转换行为,因此在大多数情况下,最好将其解析为DateTimeOffset而不是DateTime

答案 1 :(得分:1)

不要使用DateTime来解析字符串,而是使用DateTimeOffset。然后,您可以使用生成的LocalDateTime的{​​{1}}或UtcDateTime属性,以显式获取本地时间或UTC时间中的字符串表示的时间。或者,您可以使用DateTimeOffset属性来检查字符串最初是否包含时区偏移。

答案 2 :(得分:-2)

您可以明确指定将字符串解释为本地时间:

Console.Write
(
    DateTime.Parse("2018-11-17T01:00:00", null, DateTimeStyles.AssumeLocal).Kind
);

输出:

Local