我有一个基本的字典如下:

sample = {}
sample['title'] = "String"
sample['somedate'] = somedatetimehere

当我尝试做jsonify(sample)时,我得到:

TypeError: datetime.datetime(2012, 8, 8, 21, 46, 24, 862000) is not JSON serializable

我该怎么做才能使我的字典样本克服上面的错误呢?

注意:虽然它可能不相关,字典是从mongodb的记录检索中生成的,当我打印出str(sample['somedate'])时,输出是2012-08-08 21:46:24.862000。


当前回答

通常有几种方法来序列化日期时间,比如:

ISO字符串,短,可以包含时区信息,例如@jgbarah的答案 时间戳(时区数据丢失),例如@JayTaylor的答案 属性字典(包括时区)。

如果您同意最后一种方法,json_tricks包将处理日期、时间和日期时间(包括时区)。

from datetime import datetime
from json_tricks import dumps
foo = {'title': 'String', 'datetime': datetime(2012, 8, 8, 21, 46, 24, 862000)}
dumps(foo)

这使:

{"title": "String", "datetime": {"__datetime__": null, "year": 2012, "month": 8, "day": 8, "hour": 21, "minute": 46, "second": 24, "microsecond": 862000}}

所以你要做的就是

`pip install json_tricks`

然后导入从json_tricks而不是json。

不将其存储为单个字符串、int型或float型的优势体现在解码时:如果你遇到的只是字符串,特别是int型或float型,你需要了解一些关于数据的信息,以知道它是否是一个datetime。作为dict,您可以存储元数据,以便自动解码,这就是json_tricks为您做的。它也很容易为人类编辑。

免责声明:这是我做的。因为我也有同样的问题。

其他回答

我今天遇到了这个问题,我发现了一种叫做泡菜的东西。它是一个用于序列化python对象的内置库,也可以从pickle文件加载它。

我发现pickle和json之间唯一的区别是pickle文件是二进制文件,而json是通常的文本文件。

它不会对datetime对象造成任何问题。

如果你正在使用django模型,你可以直接将encoder=DjangoJSONEncoder传递给field构造函数。它会像魔法一样有效。

from django.core.serializers.json import DjangoJSONEncoder 
from django.db import models 
from django.utils.timezone import now


class Activity(models.Model):
    diff = models.JSONField(null=True, blank=True, encoder=DjangoJSONEncoder)


diff = {
    "a": 1,
    "b": "BB",
    "c": now()
}

Activity.objects.create(diff=diff)
def j_serial(o):     # self contained
    from datetime import datetime, date
    return str(o).split('.')[0] if isinstance(o, (datetime, date)) else None

以上用途的使用:

import datetime
serial_d = j_serial(datetime.datetime.now())
if serial_d:
    print(serial_d)  # output: 2018-02-28 02:23:15

将日期转换为字符串

sample['somedate'] = str( datetime.utcnow() )

这个Q一遍又一遍地重复——一种简单的方法来修补json模块,这样序列化将支持datetime。

import json
import datetime

json.JSONEncoder.default = lambda self,obj: (obj.isoformat() if isinstance(obj, datetime.datetime) else None)

然后像往常一样使用json序列化-这次使用datetime序列化为isoformat。

json.dumps({'created':datetime.datetime.now()})

导致:'{"created": "2015-08-26T14:21:31.853855"}'

查看更多细节和一些警告的话: StackOverflow: Python和JavaScript之间的JSON日期时间