DateTimeStyles.往返类枚举均值
本文关键字:枚举 DateTimeStyles | 更新日期: 2023-09-27 18:07:53
我在这里阅读这个答案,在那里我遇到了这个枚举值DateTimeStyles.RoundtripKind
。我现在试着去理解它。我查看了MSDN文档这里写着:
日期的DateTimeKind字段在DateTime对象中保留使用" 0 "转换为字符串。或";r"标准格式指定符,然后将字符串转换回DateTime对象。
上一段提到的post中input
变量所指向的时间戳如下:
<timestamp time='2016-09-16T13:45:30'>
我运行了她的代码,它可以工作。现在把所有的信息关联起来就有点麻烦了:
以上时间戳包含一些标识符
T
MSDN文档讨论了
o
和r
格式说明符,它没有告诉它是什么?如果你在我上面引用的MSDN链接上深入挖掘
DateTimeKind
枚举的更多细节,它没有提到o
和r
格式说明符。这是一个链接,上面写着:Member Name | Description -------------------------------------------------------------------------------- Local | The time represented is local time.
Unspecified | The time represented is not specified as either local time or Coordinated Universal Time (UTC).
Utc | The time represented is UTC.
所以有人能帮助我理解DateTimeStyles.RoundtripKind
枚举和它是如何工作的吗?
所以我终于能够理解这一点,并在这里分享相同的信息,如果它对其他人也有帮助:
第一部分是c# DateTime对象到字符串的转换。有许多格式说明符可以做到这一点,但对我们来说,r和o格式说明符与DateTimeStyles.RoundtripKind有关。您可以在这里看到所有日期时间格式说明符。看看在代码中使用这些格式说明符进行转换时会发生什么://r corresponds to RFC 1123 format (GMT date time format)
var gmtDateTimeString = DateTime.Now.ToString("r"); //gives Fri, 23 Sep 2016 15:39:21 GMT
//o corresponds to ISO 8601 (Local date time format)
var localDateTimeString = DateTime.Now.ToString("o"); //gives 2016-09-23T15:39:21.8899216+05:30
你可以清楚地看到输出的字符串日期时间嵌入了信息,这表明:
- Fri, 23 Sep 2016 15:39:21 GMT是DateTimeKind的。格林尼治时间Utc (文本存在)
- 2016-09-23T15:39:21.8899216+05:30表示DateTimeKind的日期时间。本地 (T字符根据ISO 8601标准存在)
现在是第二部分。如果我必须将存储在gmtDateTimeString
和localDateTimeString
中的日期时间字符串转换回日期时间对象,那么我们需要解析它们。所以在DateTimeStyles的帮助下。RoundtripKind传递给日期时间的枚举值。解析 API,您实际上表示时区信息已经在字符串中烘烤,API使用该信息适当地解析日期时间。
通常情况下,当日期时间数据以XML格式通过电线传输时,使用ISO 8601格式,这是我在帖子中看到的,我在这个帖子中发布问题之前提到过。因此,在解析从XML文档获得的日期时间字符串时,使用DateTimeStyles是合适的。RoundtripKind根据字符串中存在的时区信息获取正确的日期时间值。
我很难理解其他的答案,所以我决定自己做一些研究。幸运的是,. net库的源代码可以在线获得。
DateTimeStyles.RoundTripKind
在源代码中有注释:
// Attempt to preserve whether the input is unspecified, local or UTC
它或多或少就像DateTimeStyles.RoundTripKind
上的MSDN文档一样模糊:
当使用"o"或"r"标准格式说明符将DateTime对象转换为字符串,然后将字符串转换回DateTime对象时,日期的DateTimeKind字段将被保留。
通过浏览参考源网站,可以看到DateTimeStyles.RoundTripKind
的使用很少。实际上,如果设置了该标志,则可以将DateTime
的类型修改为DateTimeKind.Utc
。这就是设置这个标志的效果:有时解析后的DateTime
值的Kind
属性被设置为Utc
。
具体发生的时间由内部标志ParseFlags.TimeZoneUtc
控制。确定何时设置此标志更为复杂,但据我所知,如果使用Z
或GMT
指定时区,解析器将设置此标志。在源代码中有一个注释:
// NOTENOTE : for now, we only support "GMT" and "Z" (for Zulu time).
我的结论是,如果使用o
或r
格式化时间戳,并且在解析时间戳时使用DateTimeStyles.RoundTripKind
,则如果字符串中的时区是UTC时区,则结果DateTime
值的Kind
设置为Utc
。
但是,如果没有设置标志会发生什么?确定这一点的最佳方法是对这两个格式说明符进行一些实际测试。
往返("O", "O")格式说明符
当使用o
格式指定符时,时间戳的时区将为UTC的Z
或与UTC的偏移量+/-
(例如2017-02-26T22:55:15.4923368+01:00
)。下面的表格显示了从往返时间戳解析的DateTime
值的Kind
属性值:
如果你想解析一个往返格式的时间戳,并且你希望时间戳的时区是UTC,那么你应该指定DateTimeStyles.RoundTripKind
,以确保解析的DateTime
值类型为Utc
。
RFC1123 ("R", "R")格式说明符
当使用r
格式说明符时,时间戳将始终包含GMT
(即使原始DateTime
的类型不是Utc
),因此r
格式的表不需要Timezone
列。但是,我发现DateTime.Parse
和DateTime.ParseExact
在解析RFC1123时间戳时的行为不同:
当使用Parse
方法时,RFC1123格式的时间戳的行为与往返格式的UTC时间戳相同。然而,由于某种原因,ParseExact
方法忽略了DateTimeStyles.RoundTripKind
标志。在解析往返格式化时间戳时不会出现这种情况。
如果你想解析RFC1123格式的时间戳,你应该使用Parse
方法并指定DateTimeStyles.RoundTripKind
,或者如果你喜欢ParseExact
方法,你必须将解析的时间戳类型修改为Utc
。您可以使用DateTime.SpecifyKind
方法创建一个新的时间戳。
解析往返时间戳和RFC1123时间戳时指定DateTimeStyles.RoundTripKind
,以确保解析后的DateTime
值的Kind
属性为Utc
。
如果一个往返时间戳有一个非零的偏移量,那么你必须将时间戳解析成DateTimeOffset
的值来保留偏移量(Local
不会告诉你偏移量是什么——只是告诉你它可能与0不同)。
不使用DateTime.ParseExact
来解析RFC1123时间戳(或者在时间戳被解析后将类型更改为Utc
)。
往返格式意味着"机器消费"-它可以很容易地解析回相同的DateTime值。
大多数其他格式是供"人使用"的,用于向人显示日期(可能包括时间)。