我有一个基本的词典如下:
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
.
29 回答
在使用sqlalchemy在类中编写序列化装饰器时,我收到了相同的错误消息 . 所以代替:
我简单地借用了jgbarah的使用isoformat()并将原始值附加到isoformat()的想法,现在它看起来像:
如果您想要自己的格式,请快速修复
更新于2018年
最初的答案符合MongoDB“date”字段的表示方式:
{"$date": 1506816000000}
如果你想要一个通用的Python解决方案来序列化
datetime
到json,请查看@jjmontes' answer以获得一个不需要依赖的快速解决方案 .当您使用mongoengine(每条评论)并且pymongo是一个依赖项时,pymongo有内置的实用程序来帮助json序列化:
http://api.mongodb.org/python/1.10.1/api/bson/json_util.html
用法示例(序列化):
用法示例(反序列化):
Django
Django提供了一个原生的
DjangoJSONEncoder
序列化器来处理这种正确的 .见https://docs.djangoproject.com/en/dev/topics/serialization/#djangojsonencoder
我注意到
DjangoJSONEncoder
与使用自定义_1856348之间的一个区别是:这是Django剥离了一些数据:
因此,在某些情况下,您可能需要小心 .
基于其他答案,基于特定序列化器的简单解决方案,只需将
datetime.datetime
和datetime.date
对象转换为字符串 .如图所示,代码只是检查以确定对象是否为
datetime.datetime
或datetime.date
类,然后使用.isoformat()
生成它的序列化版本,根据ISO 8601格式,YYYY-MM-DDTHH:MM:SS(很容易由JavaScript解码) . 如果寻求更复杂的序列化表示,可以使用其他代码而不是str()(例如,参见该问题的其他答案) . 代码以引发异常结束,以处理使用非可序列化类型调用的情况 .这个json_serial函数可以用如下:
有关如何使用json.dumps的默认参数的详细信息,请参见Section Basic Usage of the json module documentation .
我的快速和脏的JSON转储吃日期和所有东西:
我刚遇到这个问题,我的解决方案是子类
json.JSONEncoder
:在你的电话中做了类似的事情:
json.dumps(yourobj, cls=DateTimeEncoder)
.isoformat()
我从上面的一个答案得到了 .将日期转换为字符串
对于那些不需要或不想使用pymongo库的人来说,你可以使用这个小片段轻松实现datetime JSON转换:
然后像这样使用它:
输出:
这是我的解决方案:
然后你就可以这样使用它:
我有一个类似问题的申请;我的方法是将日期时间值JSONize为6项列表(年,月,日,小时,分钟,秒);你可以将微秒作为一个7项目列表,但我没有必要:
生产环境 :
我的解决方案(我认为不那么冗长):
然后使用
jsondumps
而不是json.dumps
. 它将打印:我想要,稍后你可以通过简单的
default
方法添加其他特殊情况 . 例:这个Q一次又一次地重复 - 一种修补json模块的简单方法,使序列化支持日期时间 .
比你经常使用json序列化 - 这次将datetime序列化为isoformat .
导致:'{“created”:“2015-08-26T14:21:31.853855”}'
查看更多详情和一些警告:StackOverflow: JSON datetime between Python and JavaScript
这是一个简单的解决方案来解决“datetime not JSON serializable”问题 .
Output:-> {"date":"2015-12-16T04:48:20.024609"}
您必须提供
json.dumps
参数为json.dumps
的自定义编码器类 . 引用docs:这使用复数作为示例,但您可以轻松创建一个类来编码日期(除了我认为JSON对日期有点模糊)
最简单的方法是将日期时间格式的dict部分更改为isoformat . 该值实际上是isoformat中的一个字符串,json可以使用 .
您应该在
.datetime.now()
方法上使用.strftime()
方法将其作为可序列化方法 .这是一个例子:
输出:
如果你是在视图中使用结果一定要返回正确的响应 . 根据API,jsonify执行以下操作:
要使用json.dumps模仿此行为,您必须添加一些额外的代码行 .
你还应该返回一个dict来完全复制jsonify的响应 . 因此,整个文件将如下所示
我的解决方案
好的,现在进行一些测试 .
这是我将datetime转换为JSON并返回的完整解决方案..
产量
JSON文件
这使我能够导入和导出字符串,整数,浮点数和日期时间对象 . 它不应该难以扩展到其他类型 .
将
date
转换为string
通常,有几种方法可以序列化日期时间,例如:
ISO字符串,简短并且可以包括时区信息,例如@ jgbarah的answer
时间戳(时区数据丢失),例如@ JayTaylor的answer
属性词典(包括时区) .
如果您对最后一种方式没问题,json_tricks包处理日期,时间和日期时间,包括时区 .
这使:
所以你需要做的就是
然后从
json_tricks
导入而不是json
.解码时不会将其作为单个字符串,int或float存储的优点:如果您只遇到一个字符串或特别是int或float,您需要了解一些有关数据的信息,以了解它是否为日期时间 . 作为一个字典,您可以存储元数据,以便自动解码,这就是
json_tricks
为您所做的 . 它也很容易为人类编辑 .免责声明:它是由我制作的 . 因为我有同样的问题 .
试试这个用一个例子来解析它:
json.dumps方法可以接受一个名为default的可选参数,该参数应该是一个函数 . 每次JSON尝试转换值时,它都不知道如何转换它将调用我们传递给它的函数 . 该函数将接收有问题的对象,并期望返回该对象的JSON表示 .
如果您使用的是python3.7,那么最好的解决方案是使用datetime.isoformat()和datetime.fromisoformat();他们使用天真和有意识的
datetime
对象:输出:
如果您使用的是python3.6或更低版本,而您只关心时间值(而不是时区),那么您可以使用
datetime.timestamp()
和datetime.fromtimestamp()
代替;如果您正在使用python3.6或更低版本,并且您确实关心时区,那么您可以通过
datetime.tzinfo
获取它,但您必须自己序列化此字段;最简单的方法是在序列化对象中添加另一个字段_tzinfo
;最后,要注意所有这些例子中的精确性;
如果您在通信的两侧,可以使用 repr() 和 eval() 函数以及json .
您不应该将日期时间导入为
因为eval会抱怨 . 或者您可以将datetime作为参数传递给eval . 无论如何,这应该有效 .
当将django模型对象外部化为转储为JSON时,我遇到了同样的问题 . 这是你如何解决它 .
上述用途的用法:
实际上这很简单 . 如果您需要经常序列化日期,那么将它们作为字符串使用 . 如果需要,您可以轻松地将它们转换为datetime对象 .
如果您需要主要作为datetime对象工作,那么在序列化之前将它们转换为字符串 .
如您所见,两种情况下的输出都相同 . 只有类型不同 .
我可能不是100%正确但是,这是进行序列化的简单方法