我很難理解其他答案,所以我決定自己做一些研究。幸運的是,.NET庫的源代碼可以在線獲得。
DateTimeStyles.RoundTripKind
has a comment in the source:
// Attempt to preserve whether the input is unspecified, local or UTC
它或多或少正如含糊上DateTimeStyles.RoundTripKind
MSDN文檔:
當DateTime對象轉換爲一個日期的DateTimeKind字段被保留字符串使用「o」或「r」標準格式說明符,然後將該字符串轉換回DateTime對象。
通過瀏覽Reference Source網站,可以看出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
在解析時間戳然後將得到的DateTime
值Kind
是,如果時區的設置爲Utc
使用字符串是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
列。然而,我發現,DateTime.Parse
和DateTime.ParseExact
不同的行爲時,RFC1123時間戳解析:
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
)。
有關o和r的詳細信息,請參閱https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx –
「T」只是ISO-8601的一部分格式 –
在示例中,「T」不是格式說明符。 –