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?
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?
For cross-language projects, I found out that strings containing RfC 3339 dates are the best way to go. An RfC 3339 date looks like this:
1985-04-12T23:20:50.52Z
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:
json.dump(datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ'))
Unfortunately, Javascript's 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.
If you're certain that only Javascript will be consuming the JSON, I prefer to pass Javascript Date objects directly.
The ctime() method on datetime objects will return a string that the Javascript Date object can understand.
import datetime
date = datetime.datetime.today()
json = '{"mydate":new Date("%s")}' % date.ctime()
Javascript will happily use that as an object literal, and you've got your Date object built right in.
For the Python to JavaScript date conversion, the date object needs to be in specific ISO format, i.e. ISO format or UNIX number. If the ISO format lacks some info, then you can convert to the Unix number with Date.parse first. Moreover, Date.parse works with React as well while new Date might trigger an exception.
In case you have a DateTime object without milliseconds, the following needs to be considered. :
var unixDate = Date.parse('2016-01-08T19:00:00')
var desiredDate = new Date(unixDate).toLocaleDateString();
The example date could equally be a variable in the result.data object after an API call.
For options to display the date in the desired format (e.g. to display long weekdays) check out the MDN doc.
Apparently The “right” JSON (well JavaScript) date format is 2012-04-23T18:25:43.511Z - UTC and "Z". Without this JavaScript will use the web browser's local timezone when creating a Date() object from the string.
For a "naive" time (what Python calls a time with no timezone and this assumes is local) the below will force local timezone so that it can then be correctly converted to UTC:
def default(obj):
if hasattr(obj, "json") and callable(getattr(obj, "json")):
return obj.json()
if hasattr(obj, "isoformat") and callable(getattr(obj, "isoformat")):
# date/time objects
if not obj.utcoffset():
# add local timezone to "naive" local time
# https://stackoverflow.com/questions/2720319/python-figure-out-local-timezone
tzinfo = datetime.now(timezone.utc).astimezone().tzinfo
obj = obj.replace(tzinfo=tzinfo)
# convert to UTC
obj = obj.astimezone(timezone.utc)
# strip the UTC offset
obj = obj.replace(tzinfo=None)
return obj.isoformat() + "Z"
elif hasattr(obj, "__str__") and callable(getattr(obj, "__str__")):
return str(obj)
else:
print("obj:", obj)
raise TypeError(obj)
def dump(j, io):
json.dump(j, io, indent=2, default=default)
why is this so hard.
Simply do this:
r = json.dumps(your_json_data, default=str)
your_json_data = json.loads(r)