首页 > 解决方案 > 如何在不序列化的情况下将带有日期的文本写入 JSON 文件

问题描述

我正在从纯文本文件中读取一些文本。在做了一些修改之后,我想写另一个包含 JSON 的文件,其中也有日期格式。

当我尝试使用将其转换为 JSONjson.dumps时,它给出:

“日期时间”类型的对象不是 JSON 可序列化的

当我将它连载并将其写入文件时,它工作正常。但现在日期以字符串格式表示。我想在JSON ISO date format

这是我的代码:

def getDatetimeFromISO(s):
    d = dateutil.parser.parse(s)
    return d

with open('./parsedFiles/Data.json','w+') as f:
    parsedData = []

    for filename in os.listdir('./Data'): 
        parsed = {}
        parsed["Id"] = filename[:-4]
        breakDown = []
        with open('./castPopularityData/'+str(filename),'r') as f1:
            data = ast.literal_eval(f1.read())
            for i in range(0,len(data)):
                data[i]["date"] = getDatetimeFromISO(data[i]['date'])
                data[i]["rank"] = data[i]['rank']
                breakDown.append(data[i])
            parsed["breakDown"] = breakDown    
        parsedData.append(parsed)
        print(parsedData)
    json.dump(parsedData, f, indent=4)

如何将 ISO 日期写入 JSON 文件?

我不想序列化我的数据,这会将日期格式转换为字符串。我想将日期作为日期本身写入 JSON 文件。

标签: pythonjson

解决方案


JSON 不知道任何日期或时间类型。请参阅Python 类型表以及它们如何映射到 JSON 数据类型

要在 JSON 中表示非 JSON 原生的任何类型(例如日期或日期+时间),您必须对其进行序列化:将该值转换为具有某种特定格式的字符序列。

该类json.JSONEncoder允许扩展以满足这种需求:

为了扩展它以识别其他对象,子类化并default用另一个方法实现一个方法,o如果可能的话,它返回一个可序列化的对象,否则它应该调用超类实现(以 raise TypeError)。

您选择了 ISO 8601 序列化格式来表示日期值;这是一个不错的选择。该datetime.date类型直接支持序列化为 ISO 表示

所以现在你需要一个 JSONEncoder 子类来识别datetime.date值,并将它们序列化为 ISO 8601:

import datetime
import json

class MySpecificAppJSONEncoder(json.JSONEncoder):
    """ JSON encoder for this specific application. """

    def default(self, obj):
        result = NotImplemented
        if isinstance(obj, datetime.date):
            result = obj.isoformat()
        else:
            result = json.JSONEncoder.default(self, obj)
        return result

现在您的函数可以使用该编码器类:

json.dump(parsed_data, outfile, indent=4, cls=MySpecificAppJSONEncoder)

推荐阅读