Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

I have a string representation of a JSON object.

dumped_dict = '{"debug": false, "created_at": "2020-08-09T11:24:20"}' 

When I call json.loads with this object;

json.loads(dumped_dict) 

I get;

{'created_at': '2020-08-09T11:24:20', 'debug': False} 

There is nothing wrong in here. However, I want to know if there is a way to convert the above object with json.loads to something like this:

{'created_at': datetime.datetime(2020, 08, 09, 11, 24, 20), 'debug': False} 

Shortly, are we able to convert datetime strings to actual datetime.datetime objects while calling json.loads?

like image 646
Ozgur Vatansever Avatar asked Jan 09 '12 18:01

Ozgur Vatansever


People also ask

How do you serialize a datetime object as JSON in Python?

Serialize datetime by converting it into String You can convert dateTime value into its String representation and encode it directly, here you don't need to write any encoder. We need to set the default parameter of a json. dump() or json. dumps() to str like this json.

How do I fix the object of type datetime is not JSON serializable?

The Python "TypeError: Object of type datetime is not JSON serializable" occurs when we try to convert a datetime object to a JSON string. To solve the error, set the default keyword argument to str in your call to the json. dumps() method.

What converts .JSON file into a Python object?

Use jsonpickle module to convert JSON data into a custom Python Object. jsonpickle is a Python library designed to work with complex Python Objects. You can use jsonpickle for serialization and deserialization complex Python and JSON Data. You can refer to Jsonpickle Documentation for more detail.


2 Answers

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.

like image 103
Nicola Iarocci Avatar answered Sep 20 '22 15:09

Nicola Iarocci


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 datetime import json  def 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_dict  dumped_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.

like image 28
galarant Avatar answered Sep 22 '22 15:09

galarant