Pythonでjsonを読み込み、出力する際にdateやdatetime型を使用する
出力の時の話はよく記載がありましたが、読み込みの際に変換する方法はあまりなかったのでメモ。
概要
jsonでは日付型というのは定義されていません。(そもそもどう表現する?) そのため、pythonでjsonを読み込みの際に日付が含まれていても文字列になりますし、出力の際にdate型が含まれているとエラーになります。
対応方法としては読み込むためのloadsではobject_hook、出力のためのdumpsはdefaultというオプションがあるので、こちらを設定することで対応が可能です。
対応前のコード
import json data = '{"date" : "2019/02/08"}' d = json.loads(data) type(d['date']) # str
import json from datetime import datetime data = {'date' : datetime.now()} json.dumps(data) # TypeError: Object of type 'datetime' is not JSON serializable
対応後
詳しくは下記のコードを見てください。 出力時は型を調べて文字列に変換するだけなので何の問題もないですが、読み込み時は何らかの条件で日付を判別しdate型に変換しています。 (jsonには明示的に日付を示す構文はないためしょうがない。) ここではキーの末尾が「date」の場合に、date型に変換するようにしています。
import re import json from datetime import datetime, date DATE_FORMAT = '%Y/%m/%d' DATE_KEY = re.compile(r'date$') def _json_parser(dct): for k, v in dct.items(): if re.search(DATE_KEY, k): dct[k] = datetime.strptime(v, DATE_FORMAT).date() return dct json_str = '{"hoge_date" : "2019/01/02", "l" : [{"huga_date" : "2018/12/31"}]}' dct = json.loads(json_str, object_hook=_json_parser) print(dct) print(type(dct['hoge_date'])) # <class 'datetime.date'> print(type(dct['l'][0]['huga_date'])) # <class 'datetime.date'> def json_serial(obj): if isinstance(obj, date): return obj.strftime(DATE_FORMAT) return obj json.dumps(dct, default=json_serial)