I want to send a datetime.datetime object in serialized form from Python using JSON and de-serialize in JavaScript using JSON. What is the best way to do this?
We started with Q&A. Technical documentation is next, and we need your help.
Whether you're a beginner or an experienced developer, you can contribute.
|
You can add the 'default' parameter to json.dumps to handle this:
Which is ISO 8601 format. A more comprehensive default handler function:
Update: Added output of type as well as value. |
|||||||||||||||||||||
|
For cross language projects I found out that strings containing RfC 3339 dates are the best way to go. A RfC 3339 date looks like this:
I think most of the format is obvious. The only somewhat unusual thing may be the "Z" at the end. It stands for GMT/UTC. You could also add a timezone offset like +02:00 for CEST (Germany in summer). I personally prefer to keep everything in UTC until it is displayed. For displaying, comparisons and storage you can leave it in string format across all languages. If you need the date for calculations easy to convert it back to a native date object in most language. So generate the JSON like this:
Unfortunately Javascripts Date constructor doesn't accept RfC 3339 strings but there are many parsers available on the Internet. huTools.hujson tries to handle the most common encoding issues you might come across in Python code including date/datetime objects while handling timezones correctly. |
|||||||||||||||||||||
|
I've worked it out. Let's say you have a Python datetime object, d, created with datetime.now(). Its value is:
You can serialize it to JSON as an ISO 8601 datetime string:
The example datetime object would be serialized as:
This value, once received in the Javascript layer, can construct a Date object:
As of Javascript 1.8.5, Date objects have a toJSON method, which returns a string in a standard format. To serialize the above Javascript object back to JSON, therefore, the command would be:
Which would give you:
This string, once received in Python, could be deserialized back to a datetime object:
This results in the following datetime object, which is the same one you started with and therefore correct:
|
|||||||||||||
|
Using
Then, you can call it like this:
|
|||||||||||||
|
Here's a fairly complete solution for recursively encoding and decoding datetime.datetime and datetime.date objects using the standard library Decoding only works when the ISO date strings are values in a JavaScript literal object notation or in nested structures within an object. ISO date strings, which are items of a top-level array will not be decoded. I.e. this works:
And this too:
But this doesn't work as expected:
Here's the code:
|
|||||
|
If you're certain that only Javascript will be consuming the JSON, I prefer to pass Javascript The
Javascript will happily use that as an object literal, and you've got your Date object built right in. |
|||||||||
|
Late in the game... :) A very simple solution is to patch the json module default. For example:
Now, you can use json.dumps() as if it had always supported datetime...
This makes sense if you require this extension to the json module to always kick in and wish to not change the way you or others use json serialization (either in existing code or not). Note that some may consider patching libraries in that way as bad practice. Special care need to be taken in case you may wish to extend your application in more than one way - is such a case, I suggest to use the solution by ramen or JT and choose the proper json extension in each case. |
|||||
|
On python side:
On javascript side:
where data is result from python |
|||
|
My advice is to use a library. There are several available at pypi.org. I use this one, it it works good: https://pypi.python.org/pypi/asjson |
||||
|
Not much to add to the community wiki answer, except for timestamp! Javascript uses the following format:
Python side (for the
If you leave that Z out, frontend frameworks like angular can not display the date in browser-local timezone:
|
|||
|