2016-09-19 8 views
5

Czytałem w poście odpowiadającego here, gdzie wpadłem na to wyliczenie DateTimeStyles.RoundtripKind, które staram się zrozumieć. Spojrzałem w MSDN here który mówi:Co oznacza wyliczenie DateTimeStyles.RoundtripKind?

DateTimeKind pole data jest zachowana, gdy obiekt DateTime jest konwertowana na ciąg przy użyciu „O” lub „R” standardowym formacie specyfikator, a łańcuch jest następnie konwertowane z powrotem do obiektu DateTime.

Datownik na wejściu w poście mowa jest tak:

<timestamp time='2016-09-16T13:45:30'> 

wpadłem jej kod i nadal działa. Teraz to wszystko jest bałagan, aby połączyć wszystkie informacje mam:

  1. Powyższy datownik zawiera jakiś identyfikator T
  2. dokumentacji MSDN mówi o o i formatu r specyfikatorów które nie powiedzieć, co to jest ?
  3. Jeśli zaczniesz kopać więcej informacji na temat wyliczenia DateTimeKind na łączu MSDN, które cytowałem powyżej, nic nie mówi o specyfikacjach formatu o i r. Here jest link, który mówi:

nazwa użytkownikaOpis

Lokalna => Czas reprezentowany jest czas lokalny.

Nieokreślony => Przedstawiony czas nie jest określony jako czas lokalny lub skoordynowany czas uniwersalny (UTC).

Utc => Przedstawiony czas to UTC.

P.S. Próbowałem utworzyć powyższą tabelę, ale wygląda na to, że SO nie ma natywnego wsparcia dla tworzenia tabelarycznych struktur.

Czy ktoś może mi pomóc w zrozumieniu wyliczenia DateTimeStyles.RoundtripKind i jak to działa?

+2

Aby uzyskać szczegółowe informacje na temat o i r, zobacz https://msdn.microsoft.com/en-us/library/az4se3k1(v=vs.110).aspx –

+1

"T" jest tylko częścią ISO-8601 format –

+1

'T' nie jest specyfikatorem formatu w przykładzie. –

Odpowiedz

6

Więc byłem w końcu w stanie zrozumieć i dzieląc tę ​​samą informację tutaj, jeśli może to być pomocne dla innych też:

Pierwsza część jest przekształcenie obiektu C# DateTime do łańcucha. Istnieje wiele specyfikatorów formatu, które mogą to zrobić, ale dla nas "r" i "o" specyfikatory formatu nas dotyczą w odniesieniu do DateTimeStyles.RoundtripKind. Możesz zobaczyć wszystkie specyfikatory formatu daty w formacie here.Zobacz, co się dzieje, gdy robimy konwersję w kodzie za pomocą tych formatów specyfikatorów:

//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 

Wyraźnie widać, że czas datę ciąg jest wyjście ma informacji osadzonych wewnątrz niej, które proponuje:

  • Fri, 23 Sep 2016 15:39:21 GMT jest DateTimeKind.Utc ("GMT" tekst jest obecny)
  • 2016-09-23T15:39:21.8899216+05:30 reprezentuje czas dat DateTimeKind.Local (znak "T" jest obecny zgodnie ISO 8601 standard)

Teraz jest druga część. Jeśli muszę przekonwertować te łańcuchy daty o numerach gmtDateTimeString i localDateTimeString z powrotem na obiekt o czasie, wtedy musimy je przeanalizować. Tak więc za pomocą wartości wyliczeniowej przekazywanej do DateTimeStyles.RoundtripKind API można powiedzieć, że informacje o strefie czasowej są już upieczone w łańcuchu, a API prawidłowo analizuje datę w oparciu o tę informację.

Zwykle, gdy dane w formacie daty są przesyłane przez przewód w formacie XML, używany jest format ISO 8601, który widziałem we wpisie, o którym mówiłem przed umieszczeniem pytania w tym wątku. Tak więc podczas analizowania takiego łańcucha czasu daty uzyskanego z dokumentu XML, należałoby użyć wartości DateTimeStyles.RoundtripKind, aby uzyskać prawidłową wartość czasu daty, zgodnie z informacją o strefie czasowej występującą w łańcuchu.

2

Format "roundtrip" jest przeznaczony dla "zużycia urządzenia" - można go łatwo przetworzyć z powrotem na tę samą wartość DateTime.
Większość innych formatów służy do "spożycia przez ludzi", aby pokazać datę (ewentualnie wraz z czasem) danej osobie.

2

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 DateTimeKind 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).