Trudno mi było zrozumieć inne odpowiedzi, więc zdecydowałem się zrobić trochę resarcha. Na szczęście kod źródłowy biblioteki .NET jest dostępny online.
DateTimeStyles.RoundTripKind
has a comment in the source:
// Attempt to preserve whether the input is unspecified, local or UTC
To jest mniej więcej tak samo niejasne jak w dokumentacji MSDN na DateTimeStyles.RoundTripKind
:
DateTimeKind pole data jest zachowana, gdy obiekt DateTime przekształca się w ciąg znaków przy użyciu specyfikatora standardowego formatu "o" lub "r", a ciąg jest następnie konwertowany z powrotem do obiektu DateTime.
Nawigując po stronie Źródła danych, można zauważyć, że bardzo mało jest używane DateTimeStyles.RoundTripKind
. Zasadniczo, jeśli flaga jest ustawiona, to it may modify the kind of the DateTime
to DateTimeKind.Utc
. Jest to więc skutek ustawienia tej flagi: Czasami właściwość Kind
dla przeanalizowanej wartości DateTime
jest ustawiona na Utc
.
Dokładnie, gdy tak się dzieje, jest kontrolowana przez wewnętrzną flagę ParseFlags.TimeZoneUtc
. Bardziej skomplikowane jest ustalenie, kiedy ta flaga zostanie ustawiona, ale o ile mogę powiedzieć, że parser ustawi tę flagę, jeśli strefa czasowa jest określona przy użyciu Z
lub GMT
. Jest a comment about this in the source code:
// NOTENOTE : for now, we only support "GMT" and "Z" (for Zulu time).
Mój wniosek jest taki, że jeśli timestamp jest sformatowana albo o
lub r
i DateTimeStyles.RoundTripKind
jest używany podczas parsowania znacznika czasu wtedy Kind
otrzymanej wartości DateTime
jest ustawiony na Utc
jeśli strefa czasowa w ciąg jest strefą czasową UTC.
Co jednak dzieje się, gdy flaga nie jest ustawiona?Najlepszym sposobem ustalenia tego jest wykonanie rzeczywistego testowania dwóch specyfikatorów formatu.
The Round-trip ("O", "o") format specifier
Przy użyciu specyfikatora formatu o
strefa czasowa z datownikiem będzie albo Z
dla UTC lub +/-
przesunięcie od UTC (np 2017-02-26T22:55:15.4923368+01:00
) . Poniżej znajduje się tabela, która pokazuje wartość nieruchomości o wartości DateTime
analizowany ze znacznikiem czasu obie Kind
:
Timezone | RoundTripKind | Kind
---------+---------------+------
"Z" | Not specified | Local
"Z" | Specified | Utc
Not "Z" | Not specified | Local
Not "Z" | Specified | Local
Jeśli chcesz analizować znacznik czasu w formacie round-trip i można oczekiwać strefy czasowej sygnaturą czasową UTC należy podać wartość DateTimeStyles.RoundTripKind
, aby upewnić się, że przeanalizowana wartość DateTime
ma wartość Utc
.
The RFC1123 ("R", "R") w formacie specyfikator
Przy użyciu specyfikator formatu r
timestamp zawsze zawiera GMT
(nawet jeśli rodzaju oryginalnego DateTime
nie Utc
), co stół w przypadku formatu r
nie ma potrzeby stosowania kolumny Timezone
. Jednak odkryłem, że DateTime.Parse
i DateTime.ParseExact
zachowują się inaczej, gdy znacznik czasu RFC1123 jest analizowany:
Method | RoundTripKind | Kind
-----------+---------------+------------
Parse | Not specified | Local
Parse | Specified | Utc
ParseExact | Not specified | Unspecified
ParseExact | Specified | Unspecified
Przy wykorzystaniu metody Parse
datownik w formacie RFC1123 zachowuje się tak samo jak znacznik czasu UTC w formacie round-trip. Jednak z jakiegoś powodu metoda ParseExact
ignoruje flagę DateTimeStyles.RoundTripKind
. Nie dzieje się tak w przypadku przetwarzania sformatowanego znacznika czasu w obie strony.
Jeśli chcesz analizować znacznik czasu w formacie RFC1123 należy użyć metody Parse
i określić DateTimeStyles.RoundTripKind
lub jeśli wolisz metodę ParseExact
trzeba będzie modyfikować rodzaj analizowanej datownik do Utc
. Robisz to, tworząc nowy znacznik czasu, używając metody DateTime.SpecifyKind
.
Wnioski
Podczas analizowania round-trip i RFC1123 timestamps określić DateTimeStyles.RoundTripKind
aby upewnić się, że własność analizowanej wartości DateTime
Kind
jest Utc
.
Jeżeli timestamp round-trip ma niezerową offsetu następnie trzeba będzie analizować znacznik czasu na wartość DateTimeOffset
zachować przesunięcie (Local
nie powiedzieć, co przesunięcie jest - tylko, że to prawdopodobnie jest różny od 0).
Nie należy używać DateTime.ParseExact
do analizowania znaczników czasu RFC1123 (lub zmiany rodzaju na Utc
po przeanalizowaniu znacznika czasu).
Aby uzyskać szczegółowe informacje na temat o i r, zobacz https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx –
"T" jest tylko częścią ISO-8601 format –
'T' nie jest specyfikatorem formatu w przykładzie. –