2017-03-15 61 views
6

Mam aplikację Web API, która zwraca JSON do konsumentów, którzy nie korzystają z technologii Microsoft. Kiedy mój kontroler zwraca obiekt o właściwościach DateTime jak JSON, to serializes datę w tym formacie:Jak uzyskać, aby JSON.NET przekształcił datę/godzinę do ISO 8601?

2017-03-15T00:00:00-04:00

To daje konsumentowi trochę ból głowy jak oni oczekiwać, że będzie w normie ISO 8601 format. Niektóre badania powiedziały mi, że JSON.NET używa teraz domyślnie ISO 8601 (używam wersji 9.0.1). Kiedy uruchomić ten kod ...

Clipboard.Copy(JsonConvert.SerializeObject(DateTime.Now)); 

... mam to:

2017-03-15T09:10:13.8105498-04:00 

Wikipedia przedstawia je jako poprawne formaty ISO 8601, gdy wyrażając pełną datę i czas:

2017-03-15T11:45:42+00:00 
2017-03-15T11:45:42Z 
20170315T114542Z 

Jednak dane wyjściowe, które otrzymałem powyżej, nie pasują dokładnie do żadnego z nich. Chcę, aby formatator używał 2017-03-15T11:45:42Z.

I pewnie warta innej kwestii całkowicie, dodając poniższy wiersz w moim Web API config wydaje się być ignorowane, ponieważ w dalszym ciągu, aby powrócić JSON w terminie pierwotnie przedstawionego powyżej:

config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(new IsoDateTimeConverter()); 

Zakładam, że kiedyś Wyjaśnienie podstawowej kwestii, problem Web API może również zostać rozwiązany.

+1

Chciałbym móc to powtórzyć kilka razy. Więcej osób powinno zwracać uwagę na daty JSON z formatowaniem ISO 8601. –

Odpowiedz

10

Format otrzymujesz jest Format 8601 ISO (czytaj sekcję Times i Time Zone oznaczników w Wikipedii), to po prostu, że terminy są najwyraźniej nie doprowadzono do czasu UTC, więc są coraz strefy czasowej dołączany do daty zamiast wskaźnika strefy czasowej Zulu z Z.

Ustawienia IsoDateTimeConverter mają ustawienia, które można dostosować do własnych potrzeb. Możesz automatycznie dostosować daty do czasu UTC, ustawiając DateTimeStyles na AdjustToUniversal. Możesz również dostosować format wyjściowy, aby pominąć ułamkowe sekundy, jeśli ich nie chcesz. Domyślnie konwerter nie dostosowuje się do czasu UTC i zawiera tyle miejsc po przecinku, ile jest dostępnych sekund.

Spróbuj tego:

IsoDateTimeConverter converter = new IsoDateTimeConverter 
{ 
    DateTimeStyles = DateTimeStyles.AdjustToUniversal, 
    DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ssK" 
}; 

config.Formatters.JsonFormatter.SerializerSettings.Converters.Add(converter); 

Jeśli daty są już UTC, ale DateTimeKind na nich nie jest ustawiony na Utc jak powinno być (np to Unspecified), a następnie idealnie należy naprawić swój kod tak wskaźnik ten jest ustawiony prawidłowo przed serializacją. Jeśli jednak nie możesz tego zrobić (lub nie chcesz tego zrobić), możesz obejść go, zmieniając ustawienia konwertera tak, aby zawsze zawierał wskaźnik Z w formacie daty (zamiast korzystania ze specyfikatora K, który wygląda na DateTimeKind w dniu) i usunięcie dyrektywy AdjustToUniversal.

IsoDateTimeConverter converter = new IsoDateTimeConverter 
{ 
    DateTimeFormat = "yyyy'-'MM'-'dd'T'HH':'mm':'ss'Z'" 
}; 
+0

Dobra odpowiedź, dzięki. Użyłem części twojego początkowego przykładu i skończyłem właśnie używając 'DateTimeStyles = DateTimeStyles.AdjustToUniversal' bez formatu i wypisałem jako' 2017-03-15T04: 00: 00Z' dokładnie tak, jak chciałem. – oscilatingcretin

+0

Bardzo dobra odpowiedź. Wystarczy pamiętać, aby dodać to do pliku 'WebApiConfig.cs'.Użyłem również 'Culture = System.Globalization.CultureInfo.InvariantCulture' oraz' DateTimeFormat = "o" 'który wyprodukował serializowane daty takie jak to' 2014-12-10T17: 32: 44.4930000Z' –