java round trip,DateTimeStyles.RoundtripKind枚举是什么意思?

我很难理解其他答案,所以我决定自己做一些研究 . 幸运的是,.NET库的源代码可以在线获得 .

// Attempt to preserve whether the input is unspecified, local or UTC

使用“o”或“r”标准格式说明符将DateTime对象转换为字符串时,将保留日期的DateTimeKind字段,然后将该字符串转换回DateTime对象 .

通过浏览参考源网站,可以看出 DateTimeStyles.RoundTripKind 使用得很少 . 基本上,如果设置了标志,那么it may modify the kind of the DateTime to DateTimeKind.Utc . 所以这是设置此标志的效果:有时解析的 DateTime 值的 Kind 属性设置为 Utc .

究竟何时发生这种情况由内部标志ParseFlags.TimeZoneUtc控制 . 确定何时设置此标志会更复杂,但据我所知,如果使用 Z 或 GMT 指定时区,解析器将设置此标志 . 有a comment about this in the source code:

// NOTENOTE : for now, we only support "GMT" and "Z" (for Zulu time).

我的结论是,如果使用 o 或 r 格式化时间戳,并且在解析时间戳时使用 DateTimeStyles.RoundTripKind ,那么如果字符串中的时区是UTC时区,则生成的 DateTime 值的 Kind 将设置为 Utc .

但是,当没有设置标志时会发生什么?确定这一点的最佳方法是对两个格式说明符进行一些实际测试 .

往返(“O”,“o”)格式说明符

使用 o 格式说明符时,时间戳的时区将为 Z (UTC)或 +/- (UTC)的偏移量(例如 2017-02-26T22:55:15.4923368+01:00 ) . 这是一个表,显示从往返时间戳解析的 DateTime 值的 Kind 属性的值:

Timezone | RoundTripKind | Kind

---------+---------------+------

"Z" | Not specified | Local

"Z" | Specified | Utc

Not "Z" | Not specified | Local

Not "Z" | Specified | Local

如果要以往返格式解析时间戳并且您希望时间戳的时区为UTC,则应指定 DateTimeStyles.RoundTripKind 以确保解析的 DateTime 值具有类型 Utc .

RFC1123(“R”,“r”)格式说明符

使用 r 格式说明符时,时间戳将始终包含 GMT (即使原始 DateTime 的类型不是 Utc ),因此 r 格式的表不需要 Timezone 列 . 但是,我发现解析RFC1123时间戳时 DateTime.Parse 和 DateTime.ParseExact 的行为有所不同:

Method | RoundTripKind | Kind

-----------+---------------+------------

Parse | Not specified | Local

Parse | Specified | Utc

ParseExact | Not specified | Unspecified

ParseExact | Specified | Unspecified

使用 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 ) .

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值