2013-03-20 18 views
19

Używam starej wersji JSON.Net (4.0r4) przez jakiś czas & właśnie zaktualizowałem do najnowszej wersji (4.5r11). Zauważyłem, że terminy używane do być sformatowany jak:Dlaczego dokonano serializacji serializacji DateTime w JSON.NET?

2013-03-20T09: 00: 00.119Z

ale są teraz:

2013-03-20T09: 00: 00.119

Brakuje symbolu Z na końcu. Według Wikipedii:

Jeśli czas jest w UTC, dodać oo bezpośrednio po czasie bez spacji

ten złamał wiele mojego kodu JavaScript jak mam metodę, która konwertuje w obiekt DateTime & oczekuje on Z. Mogę to naprawić, zmieniając tę ​​funkcję, której używam, aby to zrobić & Odkryłem, że mogę ustawić DateTimeZoneHandling na DateTimeZoneHandling.Utc, ale oznacza to, że będę musiał zmienić wiele kodu C# w wielu projektach.

Zastanawiam się, dlaczego to się zmieniło.

Dzięki ...

+0

Warto jednak zapytać o to na http://json.codeplex.com/discussions. –

+2

To dziwne. Według jego [własnej dokumentacji] (http://james.newtonking.com/projects/json/help/index.html?topic=html/DatesInJSON.htm) zachowanie sprzed 4.5 było zupełnie innym formatem, a 4.5 zachowanie to ISO8601 (które zawierałoby "Z"). Czy w swojej konfiguracji masz jakieś niestandardowe konwertery? –

+1

stało się to problemem w moim projekcie. Dlaczego, na Boga, ignorowaliby standard ISO8601? – Toolkit

Odpowiedz

6

jakiej przeglądarki (ów) widzisz to nastąpić w? Ponieważ problem, z którym aktualnie się borykasz to parsowanie JavaScriptu, z mojego doświadczenia wynika, że ​​problem polega na zaokrągleniu milisekundy, a nie na obecności Z lub nie.

Spróbuj tego w IE9: http://jsfiddle.net/b9chris/HaBP8/

'2013-06-13T20:43:55.6', 
'2013-06-13T20:43:55.61', 
'2013-06-13T20:43:55.61Z', 
'2013-06-13T20:43:55.611', 
'2013-06-13T20:43:55.611Z' 

W większości przeglądarek wszystkie daty analizowania grzywny; w IE9 pierwsze 3 zawodzą, niezależnie od Z lub nie, ponieważ IE9 wymaga 3 miejsc dla liczby milisekund. Drugi 2 się uda, zi bez Z. Liczy się 3 milisekundy cyfr - Z jest nieistotne, między innymi dlatego, że JavaScript nie zawiera taktowania DateTimeKind, takiego jak .Net, więc Z lub nie jest nieistotne dla tego, jak Javascript internalizuje datę. Ponieważ liczba milisekund może czasami wynosić 1 lub 2 w zależności od czasu, jeśli mijasz znaczniki czasu, otrzymasz losowe niepowodzenia.

I've reported this as a bug on the Json.Net Codeplex page; został zwolniony przez opiekuna w komentarzach do błędu i zamknięty. Przejdź do otwartego źródła.

Można obejść ten błąd przy użyciu kodu w tej odpowiedzi:

https://stackoverflow.com/a/15939945/176877

Żeby było jasne, że brak jest nieprawidłowy Z Json.NET na części, jeśli emituje bez niej DateTimeKind.UTC, ale to nie jest nieważna data ISO-8601 bardziej ogólnie - brak Z domyśle oznacza Czas lokalny:

http://en.wikipedia.org/wiki/ISO_8601#Times

Jeżeli żadna informacja UTC relacja jest podana z reprezentacją czasu, czas jest zakładany do być w czasie lokalnym.

I jak wspomniano powyżej Analiza JavaScriptu nie dba o Z, więc dla twoich celów nie ma to znaczenia.

Uwaga: możesz również nie przekazać UTC do JSON.Net i wywołać ten problem. Obiekty DateTime w języku C# mogą być rodzaju Local, Unspecified, or UTC. Nie należy zakładać, że DateTimes, które nie są UTC są w rzeczywistości UTC; podanie go bez informacji o strefie czasowej jest najbezpieczniejszym zakładem. Struktura .Net DateTime wstrzymuje się w strefach czasowych, więc JSON.Net pozostaje bez wyboru, ale emituje domyślne DateTimes (DateTimeKind.Unspecified) jako Local, z wyłączeniem integracji z .Net TimeZone library.

+0

Dla każdego, kto przyjmując, że wartości DateTime są lokalne, nie będzie go przecinał, zawsze istnieje typ DateTimeOffset. – Shaun

3

Jeśli masz dane UTC w serwerze należy wyraźnie określone własności DateTimeZoneHandling

//serializer fix 
     config.Formatters.Clear(); 
     config.Formatters.Add(new JsonMediaTypeFormatter() 
     { 
      SerializerSettings = new JsonSerializerSettings() { 
       ContractResolver=new CamelCasePropertyNamesContractResolver(), 
       DateTimeZoneHandling = DateTimeZoneHandling.Utc}, 

     }); 

Po tym DateTime ma "Z" na końcu: 2017-05-11T00: 35: 20.8242381 Z

Powiązane problemy