How to convert to a Python datetime object with JSON.loads? How to convert to a Python datetime object with JSON.loads? json json

How to convert to a Python datetime object with JSON.loads?


My solution so far:

>>> json_string = '{"last_updated": {"$gte": "Thu, 1 Mar 2012 10:00:49 UTC"}}'>>> dct = json.loads(json_string, object_hook=datetime_parser)>>> dct{u'last_updated': {u'$gte': datetime.datetime(2012, 3, 1, 10, 0, 49)}}def datetime_parser(dct):    for k, v in dct.items():        if isinstance(v, basestring) and re.search("\ UTC", v):            try:                dct[k] = datetime.datetime.strptime(v, DATE_FORMAT)            except:                pass    return dct

For further reference on the use of object_hook: JSON encoder and decoder

In my case the json string is coming from a GET request to my REST API. This solution allows me to 'get the date right' transparently, without forcing clients and users into hardcoding prefixes like __date__ into the JSON, as long as the input string conforms to DATE_FORMAT which is:

DATE_FORMAT = '%a, %d %b %Y %H:%M:%S UTC'

The regex pattern should probably be further refined

PS: in case you are wondering, the json_string is a MongoDB/PyMongo query.


You need to pass an object_hook. From the documentation:

object_hook is an optional function that will be called with the result of any object literal decoded (a dict). The return value of object_hook will be used instead of the dict.

Like this:

import datetimeimport jsondef date_hook(json_dict):    for (key, value) in json_dict.items():        try:            json_dict[key] = datetime.datetime.strptime(value, "%Y-%m-%dT%H:%M:%S")        except:            pass    return json_dictdumped_dict = '{"debug": false, "created_at": "2020-08-09T11:24:20"}'loaded_dict = json.loads(dumped_dict, object_hook=date_hook)

If you also want to handle timezones you'll have to use dateutil instead of strptime.


I would do the same as Nicola suggested with 2 changes:

  1. Use dateutil.parser instead of datetime.datetime.strptime
  2. Define explicitly which exceptions I want to catch. I generally recommend avoiding at all cost having an empty except:

Or in code:

import dateutil.parserdef datetime_parser(json_dict):    for (key, value) in json_dict.items():        try:            json_dict[key] = dateutil.parser.parse(value)        except (ValueError, AttributeError):            pass    return json_dictstr = "{...}"  # Some JSON with dateobj = json.loads(str, object_hook=datetime_parser)print(obj)