Dictionary type data is often exchanged with json in python, but the dictionary value is retained by datetime, and when making a character string or file, `` `" YYYY-MM-DD HH-MN-SS " Make a note of how to handle it with the string ````.
It can be a string with a function called isoformat for datetime. I'll leave the separator blank.
In [1]: from datetime import datetime
In [2]: t1 = datetime.now()
In [3]: t1.isoformat()
Out[3]: '2020-05-08T22:16:39.287433'
In [4]: t1.isoformat(" ")
Out[4]: '2020-05-08 22:16:39.287433'
You can also use more strftime.
In [5]: t1.strftime("%Y/%m/%d %H:%M:%S.%f")
Out[5]: '2020/05/08 22:16:39.287433'
Conversely, use stfptime to convert a string to datetime.
In [6]: t2 = datetime.strptime("2020-01-02 20:03:12.345678", "%Y-%m-%d %H:%M:%S.%f")
In [7]: t2
Out[7]: datetime.datetime(2020, 1, 2, 20, 3, 12, 345678)
I use json.dump and json.dumps, but at this time I can set a function to default as an argument and convert datetime to the desired string in that function. Below, from "JSON Encoder and Decoder":
If you specify> default, specify a function, and this function will be called for objects that cannot be serialized otherwise. The function must return the object in a JSON-encoded version, or throw a TypeError. If not specified, TypeError will be thrown.
It seems correct to pick up TypeError.
import json
from datetime import datetime, date
def default(o):
if hasattr(o, "isoformat"):
return o.isoformat()
else:
return str(o)
#Make a dictionary and set the current time as a value.
dict1 = {"time1": datetime.now(), "time2": datetime.now()}
print( "dict1={}".format(dict1))
print( "str(dict1)={}".format(str(dict1)) )
#Export the dictionary
s_dict1 = json.dumps(dict1, default=default)
print( "s_dict1={}".format(s_dict1) )
The execution result is as follows.
dict1={'time1': datetime.datetime(2020, 5, 8, 22, 57, 18, 564149), 'time2': datetime.datetime(2020, 5, 8, 22, 57, 18, 564163)}
str(dict1)={'time1': datetime.datetime(2020, 5, 8, 22, 57, 18, 564149), 'time2': datetime.datetime(2020, 5, 8, 22, 57, 18, 564163)}
s_dict1={"time1": "2020-05-08 22:57:18.564149", "time2": "2020-05-08 22:57:18.564163"}
It is a character string properly. In the implementation of the default function, isoformat is checked by whether it is `` hasattr```, but for example, ```is instance (o, (datetime, date)) ``` or
`type (o) .__ name__ == You can also use "datetime" ``` and so on.
Use json.load to read. Here customized reads can be set with object_hook.
object_hook is an optional function that is called on the result (dict) of any object literal being decoded. The return value of object_hook is used instead of dict. This feature can be used to implement your own decoders (eg JSON-RPC class hinting).
def object_hook(obj):
new_dic = dict()
for o in obj:
try:
new_dic[str(o)] = datetime.strptime(obj[o], '%Y-%m-%d %H:%M:%S.%f')
except TypeError:
new_dic[str(o)] = obj[o]
pass
return new_dic
s_dic = """{"time1": "2020-05-08 22:57:18.564149", "time2": "2020-05-08 22:57:18.564163"}"""
print( "s_dic={}".format(s_dic) )
dic = json.loads(s_dic, object_hook=object_hook)
print( "dic={}".format(dic) )
The execution result is as follows.
s_dic={"time1": "2020-05-08 22:57:18.564149", "time2": "2020-05-08 22:57:18.564163"}
dic={'time1': datetime.datetime(2020, 5, 8, 22, 57, 18, 564149), 'time2': datetime.datetime(2020, 5, 8, 22, 57, 18, 564163)}
It is properly datetime.datetime.
With that, I was able to implement the desired implementation and survived the day today.
--It also shows how to implement default in a class that inherits json.JSONEncoder and specify this class in the cls argument of dumps. Which is more convenient? ――I use datetime almost all the time, but it's a bit dull to implement this every time. Is there any good way?
(2020/05/08)
――After that, what about this? What used to be loaded in float64 is now str. I was in trouble. (2020/05/12)
Recommended Posts