让 C# 为已解析的 ISO 8601 字符串正确设置 Kind 属性
Getting C# to correctly set the Kind property for a parsed ISO 8601 string
我很难理解为什么要解析 ISO 8601 formatted string that is parsed by DateTime's Parse
method doesn't set the Kind
property of the new DateTime
object correctly. I've reviewed the post How to create a .NET DateTime from ISO 8601 format 并且结合 ISO 文档看来 Parse
方法应该能够设置 Kind
值,但是它是没有。
示例:
Console.Write(System.DateTime.Parse("2018-11-17T01:00:00").Kind);
Returns:未指定
然而,根据 ISO 标准,这是一种有效格式,表明值是本地时间。
Time zones in ISO 8601 are represented as local time (with the location unspecified), as UTC, or as an offset from UTC. If no UTC relation information is given with a time representation, the time is assumed to be in local time.
Coordinated Universal Time (UTC)
If the time is in UTC, add a Z directly after the time without a space. Z is the zone designator for the zero UTC offset
更奇怪的是,在字符串中添加 Z 会将 Kind
属性 设置为 Local。
为了为 UTC 字符串正确设置 Kind
值,Parse
方法中需要 RoundtripKind 的 DateTimeStyle。但是,如果从字符串中删除 Z,Kind
将再次设置为未指定。
这是 DateTime class 的问题吗?
Microsoft 没有遵循 ISO 标准吗?
还是我不了解 ISO 标准?
您可以明确指定该字符串应解释为本地时间:
Console.Write
(
DateTime.Parse("2018-11-17T01:00:00", null, DateTimeStyles.AssumeLocal).Kind
);
输出:
Local
不要使用DateTime
解析字符串,而是使用DateTimeOffset
。然后,您可以使用生成的 DateTimeOffset
的 LocalDateTime
或 UtcDateTime
属性 显式获取本地时间或 UTC 时间的字符串表示的时间。或者您可以使用 Offset
属性 检查字符串最初是否包含时区偏移量。
要解析 ISO 8601 字符串并适当设置 DateTimeKind
,您可以使用 DateTimeStyles.RoundtripKind
with either the o
standard format specifier or a custom string that includes 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
。
我很难理解为什么要解析 ISO 8601 formatted string that is parsed by DateTime's Parse
method doesn't set the Kind
property of the new DateTime
object correctly. I've reviewed the post How to create a .NET DateTime from ISO 8601 format 并且结合 ISO 文档看来 Parse
方法应该能够设置 Kind
值,但是它是没有。
示例:
Console.Write(System.DateTime.Parse("2018-11-17T01:00:00").Kind);
Returns:未指定
然而,根据 ISO 标准,这是一种有效格式,表明值是本地时间。
Time zones in ISO 8601 are represented as local time (with the location unspecified), as UTC, or as an offset from UTC. If no UTC relation information is given with a time representation, the time is assumed to be in local time.
Coordinated Universal Time (UTC)
If the time is in UTC, add a Z directly after the time without a space. Z is the zone designator for the zero UTC offset
更奇怪的是,在字符串中添加 Z 会将 Kind
属性 设置为 Local。
为了为 UTC 字符串正确设置 Kind
值,Parse
方法中需要 RoundtripKind 的 DateTimeStyle。但是,如果从字符串中删除 Z,Kind
将再次设置为未指定。
这是 DateTime class 的问题吗?
Microsoft 没有遵循 ISO 标准吗?
还是我不了解 ISO 标准?
您可以明确指定该字符串应解释为本地时间:
Console.Write
(
DateTime.Parse("2018-11-17T01:00:00", null, DateTimeStyles.AssumeLocal).Kind
);
输出:
Local
不要使用DateTime
解析字符串,而是使用DateTimeOffset
。然后,您可以使用生成的 DateTimeOffset
的 LocalDateTime
或 UtcDateTime
属性 显式获取本地时间或 UTC 时间的字符串表示的时间。或者您可以使用 Offset
属性 检查字符串最初是否包含时区偏移量。
要解析 ISO 8601 字符串并适当设置 DateTimeKind
,您可以使用 DateTimeStyles.RoundtripKind
with either the o
standard format specifier or a custom string that includes 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
。