Skip to content

Instantly share code, notes, and snippets.

@jlumbroso
Created May 16, 2022 02:16
Show Gist options
  • Save jlumbroso/d78e8b96d9dd93a46c51642c9a1146a9 to your computer and use it in GitHub Desktop.
Save jlumbroso/d78e8b96d9dd93a46c51642c9a1146a9 to your computer and use it in GitHub Desktop.
Simple, datetime-aware JSON encoding/decoding in Python.
# Copyright (c) 2022, Jérémie Lumbroso <[email protected]>
#
# Simple datetime-aware JSON in Python
#
# Usage:
# - json_timestamp_loads just() like json.loads()
# - json_timestamp_dumps just() like json.dumps()
import datetime
import dateutil.parser
import json
import typing
KEYNAMES_WITH_TIMESTAMPS = [
"date", "timestamp", "last_updated", "last_created", "last_edited",
]
class JSONDateTimeEncoder(json.JSONEncoder):
"""
Subclass of `json.JSONEncoder` which is able to deserialize `datetime`
and `date` objects.
"""
# override the default method
def default(self, obj: typing.Any) -> typing.Any:
if isinstance(obj, (datetime.date, datetime.datetime)):
return obj.isoformat()
def json_timestamp_decoder(obj: typing.Dict) -> typing.Dict:
"""
Hook method that takes a dictionary and returns one in which qualifying
have been parsed into `date` and `datetime` objects.
"""
for key, value in obj.items():
# check if key is susceptible to contain a date (a bit hackish!)
if key not in KEYNAMES_WITH_TIMESTAMPS:
continue
# try to parse the datetime
try:
obj[key] = dateutil.parser.parse(value)
except ValueError:
pass
return obj
def json_timestamp_loads(s, **kwargs):
"""
Returns a Python object from `s` with `datetime` and `date` deserialization.
"""
return json.loads(s, object_hook=json_timestamp_decoder, **kwargs)
def json_timestamp_dumps(obj, **kwargs):
"""
Returns a JSON string representation of `obj` with `datetime` and
`date` deserialization.
"""
return json.dumps(
obj,
cls=JSONDateTimeEncoder,
**kwargs,
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment