📜  python json 10: Datetime与json的相互转化

📅  最后修改于: 2020-09-04 07:32:36             🧑  作者: Mango

当我们尝试转换Python的Datetime到json数据时,我们可能遇到 Object of type datetime is not JSON serializable这样的错误。

因为我们介绍几种Datetime转换我json数据的方法。

1.使用JSONEncoder

如果我们需要做一些定制化的转换事,可以扩展json.JSONEncoder,一般需要重写SONEncoder的default(),例如我们可以将DateTime值转换为ISO格式,以便可以对其进行序列化。

根据ISO 8601,它将使用isoformat()方法将DateTime值转换为ISO格式YYYY-MM-DDTHH:MM:SS,其更易于编码和解码的格式。

import json
import datetime
from json import JSONEncoder

employee = {
    "id": 456,
    "name": "William Smith",
    "salary": 8000,
    "joindate": datetime.datetime.now()
}

# subclass JSONEncoder
class DateTimeEncoder(JSONEncoder):
        #Override the default method
        def default(self, obj):
            if isinstance(obj, (datetime.date, datetime.datetime)):
                return obj.isoformat()

print("Printing to check how it will look like")
print(DateTimeEncoder().encode(employee))

print("Encode DateTime Object into JSON using custom JSONEncoder")
employeeJSONData = json.dumps(employee, indent=4, cls=DateTimeEncoder)
print(employeeJSONData)

输出效果:

Printing to check how it will look like
{"id": 456, "name": "William Smith", "salary": 8000, "joindate": "2020-01-08T18:52:50.637635"}
Encode DateTime Object into JSON using custom JSONEncoder
{
    "id": 456,
    "name": "William Smith",
    "salary": 8000,
    "joindate": "2020-01-08T18:52:50.637635"
}

转换为DateTime

使用json.loads()方法的object_hook参数

import json
import dateutil.parser

# custom Decoder
def DecodeDateTime(empDict):
   if 'joindate' in empDict:
      empDict["joindate"] = dateutil.parser.parse(empDict["joindate"])
      return empDict
jsonData = """{"id": 456, "name": "William Smith", "saley": 8000, "joindate": "2020-01-08T15:29:52.040435"}"""

# use of object_hook
decodedJSON = json.loads(jsonData, object_hook=DecodeDateTime)
print(decodedJSON)

打印输出:

{'id':456,'name':'William Smith','saley':8000,'joindate':datetime.datetime(2020,1,8,15,15,29,52,40435)}

2.使用字符串

直接json.dump()json.dumps()的默认参数default=str

import json
import datetime

employee = {
    "id": 456,
    "name": "William Smith",
    "salary": 8000,
    "joindate": datetime.datetime.now()
}
print("JSON Data")
print(json.dumps(employee, default=str))

输出如下:

JSON Data
{"id": 456, "name": "William Smith", "salary": 8000, "joindate": "2020-01-08 18:39:30.161488"}

3.使用定制化的函数,并传递给json.dumps()的default

import json
import datetime

employee = {
    "id": 456,
    "name": "William Smith",
    "saley": 8000,
    "joindate": datetime.datetime.now()
}

def default(obj):
    if isinstance(obj, (datetime.date, datetime.datetime)):
        return obj.isoformat()

print("Employee JSON Data")
print(json.dumps(employee, default=default))

4.使用Bson模块

bson模块具有json_util类,我们可以将其直接用于序列化并dateTime转换为JSON,而无需进行任何显式转换。

import json
import datetime
from bson import json_util

employee = {
    "id": 456,
    "name": "William Smith",
    "salary": 8000,
    "joindate": datetime.datetime.now()
}

jsonData = json.dumps(employee, default=json_util.default)
print(jsonData)

jsonData = """{"id": 456, "name": "William Smith", "saley": 8000, "joindate": "2020-01-08T15:29:52.040435"}"""

# Deserialization
decodedJson = json.loads(jsonData, object_hook=json_util.object_hook)