Chcę wysłać obiekt datetime.datetime w postaci serializowanej z Pythona za pomocą JSON i usuń serializację w JavaScript za pomocą JSON. Jak najlepiej to zrobić?
javascript
python
json
Peter Mortensen
źródło
źródło
Odpowiedzi:
Możesz dodać parametr „default” do json.dumps, aby to obsłużyć:
Co to jest ISO 8601 formatem .
Bardziej kompleksowa domyślna funkcja obsługi:
Aktualizacja: Dodano wynik zarówno typu, jak i wartości.
Aktualizacja: obsługuje także datę
źródło
dthandler = lambda obj: obj.isoformat() if isinstance(obj, datetime) else json.JSONEncoder().default(obj)
W przypadku projektów międzyjęzykowych odkryłem, że ciągi zawierające daty RfC 3339 są najlepszym sposobem. Data RfC 3339 wygląda następująco:
Myślę, że większość formatu jest oczywista. Jedyną dość niezwykłą rzeczą może być „Z” na końcu. Oznacza GMT / UTC. Możesz również dodać przesunięcie strefy czasowej, takie jak +02: 00 dla CEST (Niemcy latem). Osobiście wolę trzymać wszystko w UTC, dopóki nie zostanie wyświetlone.
Do wyświetlania, porównań i przechowywania możesz pozostawić go w formacie ciągu we wszystkich językach. Jeśli potrzebujesz daty do obliczeń, łatwo przekonwertuj ją na natywny obiekt daty w większości języków.
Więc wygeneruj JSON w ten sposób:
Niestety konstruktor daty Javascript nie akceptuje ciągów RfC 3339, ale w Internecie dostępnych jest wiele parserów .
huTools.hujson próbuje poradzić sobie z najczęstszymi problemami z kodowaniem, które mogą wystąpić w kodzie Pythona, w tym z obiektami daty / daty i godziny, przy prawidłowej obsłudze stref czasowych.
źródło
datetime
: datetime.isoformat (), jak i przezsimplejson
, który domyślnie zrzucadatetime
obiekty jakoisoformat
ciągi znaków. Nie ma potrzeby ręcznegostrftime
hakowania.datetime
obiektów naisoformat
ciąg. Dla mniesimplejson.dumps(datetime.now())
wydajnośćTypeError: datetime.datetime(...) is not JSON serializable
json.dumps(datetime.datetime.now().isoformat())
tam, gdzie dzieje się magia.Rozpracowałem to.
Załóżmy, że masz obiekt Pytetime datetime, d , utworzony za pomocą datetime.now (). Jego wartość to:
Możesz serializować to do JSON jako ciąg datetime ISO 8601:
Przykładowy obiekt datetime zostałby serializowany jako:
Ta wartość, po otrzymaniu w warstwie JavaScript, może utworzyć obiekt Date:
Począwszy od JavaScript 1.8.5, obiekty Date mają metodę toJSON, która zwraca ciąg znaków w standardowym formacie. Aby serializować powyższy obiekt JavaScript z powrotem do JSON, polecenie powinno wyglądać następująco:
Co dałoby ci:
Ten ciąg, raz otrzymany w Pythonie, można przekształcić z postaci szeregowej z powrotem do obiektu datetime:
Powoduje to powstanie następującego obiektu datetime, który jest tym samym, który zacząłeś i dlatego jest poprawny:
źródło
Za pomocą
json
można podklasować JSONEncoder i przesłonić metodę default (), aby zapewnić własne niestandardowe serializatory:Następnie możesz nazwać to tak:
źródło
obj.isoformat()
. Możesz także użyć bardziej popularnegodumps()
wywołania, które pobiera inne przydatne argumenty (jakindent
): simplejson.dumps (myobj, cls = JSONEncoder, ...)Oto dość kompletne rozwiązanie do rekurencyjnego kodowania i dekodowania obiektów datetime.datetime i datetime.date przy użyciu standardowego
json
modułu bibliotecznego . Wymaga to Python> = 2.6, ponieważ%f
kod formatu w ciągu formatu datetime.datetime.strptime () jest obsługiwany tylko od tego czasu. Aby obsługiwać Python 2.5, upuść%f
i usuń mikrosekundy z ciągu daty ISO przed próbą konwersji, ale stracisz precyzję mikrosekund. Aby zapewnić zgodność z ciągami dat ISO z innych źródeł, które mogą obejmować nazwę strefy czasowej lub przesunięcie UTC, konieczne może być również usunięcie niektórych części ciągu daty przed konwersją. Pełny parser dla ciągów daty ISO (i wielu innych formatów dat) znajduje się w module dateutil innej firmy .Dekodowanie działa tylko wtedy, gdy ciągi daty ISO są wartościami w dosłownym zapisie obiektu w JavaScript lub w zagnieżdżonych strukturach w obiekcie. Ciągi daty ISO, które są elementami tablicy najwyższego poziomu, nie będą dekodowane.
Tzn. To działa:
I to także:
Ale to nie działa zgodnie z oczekiwaniami:
Oto kod:
źródło
datetime.datetime.utcnow().isoformat()[:-3]+"Z"
że będzie dokładnie taka, jak JSON.stringify () produkuje w javascriptJeśli masz pewność, że tylko JavaScript będzie zużywał JSON, wolę przekazywać
Date
obiekty JavaScript bezpośrednio.ctime()
Metoda nadatetime
obiektach zwróci napis, że obiekt Date JavaScript może zrozumieć.JavaScript z przyjemnością użyje tego jako literału obiektu, a ty masz wbudowany obiekt Date.
źródło
.ctime()
jest BARDZO złym sposobem na przekazanie informacji o czasie,.isoformat()
jest znacznie lepszy. Co.ctime()
robi jest wyrzucić strefę czasową i czas letni jakby nie istnieją. Ta funkcja powinna zostać zabita.Późno w grze ... :)
Bardzo prostym rozwiązaniem jest załatanie domyślnego modułu json. Na przykład:
Teraz możesz używać json.dumps () tak, jakby zawsze obsługiwał datetime ...
Ma to sens, jeśli wymagasz tego rozszerzenia modułu json, aby zawsze się uruchamiało i nie chciałeś zmieniać sposobu, w jaki ty lub inni używacie serializacji json (w istniejącym kodzie lub nie).
Zauważ, że niektórzy mogą uważać łatanie bibliotek w ten sposób za złą praktykę. Należy zachować szczególną ostrożność, jeśli chcesz rozszerzyć swoją aplikację na więcej niż jeden sposób - w takim przypadku sugeruję skorzystanie z rozwiązania przez ramen lub JT i wybranie odpowiedniego rozszerzenia json w każdym przypadku.
źródło
None
. Zamiast tego możesz zgłosić wyjątek.Niewiele do dodania do odpowiedzi wiki społeczności, z wyjątkiem znacznika czasu !
JavaScript używa następującego formatu:
Strona Pythona (dla
json.dumps
obsługi zobacz inne odpowiedzi):Jeśli pominiesz to Z, frameworki takie jak kątowe nie będą mogły wyświetlać daty w lokalnej strefie czasowej przeglądarki:
źródło
Po stronie pytona:
Po stronie javascript:
gdzie dane pochodzą z Pythona
źródło
Radzę korzystać z biblioteki. Istnieje kilka dostępnych na pypi.org.
Używam tego, działa dobrze: https://pypi.python.org/pypi/asjson
źródło
Najwyraźniej „właściwy” format daty JSON (dobrze JavaScript) jest 2012-04-23T18: 25: 43.511Z - UTC i „Z”. Bez tego JavaScript będzie używał lokalnej strefy czasowej przeglądarki podczas tworzenia obiektu Date () z ciągu.
Przez „naiwny” czas (który Python nazywa czasem bez strefy czasowej i zakłada, że jest lokalny) poniżej wymusi lokalną strefę czasową, aby można ją było następnie poprawnie przekonwertować na UTC:
dlaczego to takie trudne
źródło
Do konwersji daty w Pythonie na JavaScript obiekt daty musi mieć określony format ISO, tj. Format ISO lub numer UNIX. Jeśli w formacie ISO brakuje pewnych informacji, możesz najpierw przekonwertować na numer uniksowy, używając najpierw Date.parse. Ponadto Date.parse działa również z React, podczas gdy nowa data może wywołać wyjątek.
Jeśli masz obiekt DateTime bez milisekund, należy wziąć pod uwagę następujące kwestie. :
Przykładowa data może być również zmienną w obiekcie result.data po wywołaniu interfejsu API.
Aby wyświetlić opcje wyświetlania daty w żądanym formacie (np. Wyświetlanie długich dni tygodnia), sprawdź dokument MDN .
źródło