1266 Stimmen

Wie kann man "datetime.datetime nicht JSON-seriellisierbar" überwinden?

Ich habe ein grundlegendes Wörterbuch wie folgt:

sample = {}
sample['title'] = "String"
sample['somedate'] = somedatetimehere

Wenn ich versuche, jsonify(sample) auszuführen, erhalte ich:

TypeError: datetime.datetime(2012, 8, 8, 21, 46, 24, 862000) ist nicht JSON-fähig

Was kann ich tun, damit mein Wörterbuch "sample" den oben genannten Fehler überwinden kann?

Hinweis: Obwohl es möglicherweise nicht relevant ist, werden die Wörterbücher aus dem Abrufen von Datensätzen aus mongodb generiert, bei dem, wenn ich str(sample['somedate']) ausdrucke, die Ausgabe 2012-08-08 21:46:24.862000 ist.

22voto

codingatty Punkte 1688

Ich habe eine Anwendung mit einem ähnlichen Problem; mein Ansatz war, den Datums- und Uhrzeitwert als 6-Elemente-Liste (Jahr, Monat, Tag, Stunde, Minuten, Sekunden) zu JSONisieren; Sie könnten bis zu Mikrosekunden als 7-Elemente-Liste gehen, aber ich hatte keinen Bedarf:

class DateTimeEncoder(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, datetime.datetime):
            encoded_object = list(obj.timetuple())[0:6]
        else:
            encoded_object =json.JSONEncoder.default(self, obj)
        return encoded_object

sample = {}
sample['title'] = "String"
sample['somedate'] = datetime.datetime.now()

print sample
print json.dumps(sample, cls=DateTimeEncoder)

ergibt:

{'somedate': datetime.datetime(2013, 8, 1, 16, 22, 45, 890000), 'title': 'String'}
{"somedate": [2013, 8, 1, 16, 22, 45], "title": "String"}

21voto

fiatjaf Punkte 10663

Meine Lösung (mit weniger Verbosität, denke ich):

def default(o):
    if type(o) is datetime.date or type(o) is datetime.datetime:
        return o.isoformat()

def jsondumps(o):
    return json.dumps(o, default=default)

Verwenden Sie dann jsondumps statt json.dumps. Es wird gedruckt:

>>> jsondumps({'today': datetime.date.today()})
'{"today": "2013-07-30"}'

Wenn Sie möchten, können Sie später mit einer einfachen Änderung der Methode default andere spezielle Fälle hinzufügen. Beispiel:

def default(o):
    if type(o) is datetime.date or type(o) is datetime.datetime:
        return o.isoformat()
    if type(o) is decimal.Decimal:
        return float(o)

19voto

davidhadas Punkte 2233

Diese Frage wiederholt sich immer wieder - eine einfache Möglichkeit, das json-Modul so zu patchen, dass die Serialisierung datetime unterstützt.

import json
import datetime

json.JSONEncoder.default = lambda self,obj: (obj.isoformat() if isinstance(obj, datetime.datetime) else None)

Verwenden Sie dann die JSON-Serialisierung wie gewohnt - dieses Mal mit datetime, das als isoformat serialisiert wird.

json.dumps({'created':datetime.datetime.now()})

Ergebnis: '{"created": "2015-08-26T14:21:31.853855"}'

Weitere Details und einige Worte der Vorsicht finden Sie unter: StackOverflow: JSON datetime zwischen Python und JavaScript

11voto

Sean Redmond Punkte 3834

Sie müssen eine benutzerdefinierte Encoder-Klasse mit dem cls-Parameter von json.dumps bereitstellen. Um aus den Docs zu zitieren:

>>> import json
>>> class ComplexEncoder(json.JSONEncoder):
...     def default(self, obj):
...         if isinstance(obj, complex):
...             return [obj.real, obj.imag]
...         return json.JSONEncoder.default(self, obj)
...
>>> dumps(2 + 1j, cls=ComplexEncoder)
'[2.0, 1.0]'
>>> ComplexEncoder().encode(2 + 1j)
'[2.0, 1.0]'
>>> list(ComplexEncoder().iterencode(2 + 1j))
['[', '2.0', ', ', '1.0', ']']

Dieses Beispiel verwendet komplexe Zahlen, aber Sie können genauso gut eine Klasse erstellen, um Daten zu codieren (obwohl ich denke, dass JSON etwas ungenau bei Daten ist)

11voto

ob92 Punkte 111

Hier ist eine einfache Lösung, um das Problem "datetime nicht JSON-serialisierbar" zu überwinden.

enco = lambda obj: (
    obj.isoformat()
    if isinstance(obj, datetime.datetime)
    or isinstance(obj, datetime.date)
    else None
)

json.dumps({'date': datetime.datetime.now()}, default=enco)

Ausgabe:-> {"date": "2015-12-16T04:48:20.024609"}

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X