我想发送一个datetime。从Python中使用JSON序列化datetime对象,并在JavaScript中使用JSON反序列化。最好的方法是什么?
当前回答
Here's a fairly complete solution for recursively encoding and decoding datetime.datetime and datetime.date objects using the standard library json module. This needs Python >= 2.6 since the %f format code in the datetime.datetime.strptime() format string is only supported in since then. For Python 2.5 support, drop the %f and strip the microseconds from the ISO date string before trying to convert it, but you'll loose microseconds precision, of course. For interoperability with ISO date strings from other sources, which may include a time zone name or UTC offset, you may also need to strip some parts of the date string before the conversion. For a complete parser for ISO date strings (and many other date formats) see the third-party dateutil module.
只有当ISO日期字符串是JavaScript中的值时,解码才有效 文字对象表示法或在对象内的嵌套结构中。ISO日期 作为顶级数组项的字符串将不会被解码。
例如:
date = datetime.datetime.now()
>>> json = dumps(dict(foo='bar', innerdict=dict(date=date)))
>>> json
'{"innerdict": {"date": "2010-07-15T13:16:38.365579"}, "foo": "bar"}'
>>> loads(json)
{u'innerdict': {u'date': datetime.datetime(2010, 7, 15, 13, 16, 38, 365579)},
u'foo': u'bar'}
还有这个:
>>> json = dumps(['foo', 'bar', dict(date=date)])
>>> json
'["foo", "bar", {"date": "2010-07-15T13:16:38.365579"}]'
>>> loads(json)
[u'foo', u'bar', {u'date': datetime.datetime(2010, 7, 15, 13, 16, 38, 365579)}]
但这并不是预期的那样:
>>> json = dumps(['foo', 'bar', date])
>>> json
'["foo", "bar", "2010-07-15T13:16:38.365579"]'
>>> loads(json)
[u'foo', u'bar', u'2010-07-15T13:16:38.365579']
代码如下:
__all__ = ['dumps', 'loads']
import datetime
try:
import json
except ImportError:
import simplejson as json
class JSONDateTimeEncoder(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, (datetime.date, datetime.datetime)):
return obj.isoformat()
else:
return json.JSONEncoder.default(self, obj)
def datetime_decoder(d):
if isinstance(d, list):
pairs = enumerate(d)
elif isinstance(d, dict):
pairs = d.items()
result = []
for k,v in pairs:
if isinstance(v, basestring):
try:
# The %f format code is only supported in Python >= 2.6.
# For Python <= 2.5 strip off microseconds
# v = datetime.datetime.strptime(v.rsplit('.', 1)[0],
# '%Y-%m-%dT%H:%M:%S')
v = datetime.datetime.strptime(v, '%Y-%m-%dT%H:%M:%S.%f')
except ValueError:
try:
v = datetime.datetime.strptime(v, '%Y-%m-%d').date()
except ValueError:
pass
elif isinstance(v, (dict, list)):
v = datetime_decoder(v)
result.append((k, v))
if isinstance(d, list):
return [x[1] for x in result]
elif isinstance(d, dict):
return dict(result)
def dumps(obj):
return json.dumps(obj, cls=JSONDateTimeEncoder)
def loads(obj):
return json.loads(obj, object_hook=datetime_decoder)
if __name__ == '__main__':
mytimestamp = datetime.datetime.utcnow()
mydate = datetime.date.today()
data = dict(
foo = 42,
bar = [mytimestamp, mydate],
date = mydate,
timestamp = mytimestamp,
struct = dict(
date2 = mydate,
timestamp2 = mytimestamp
)
)
print repr(data)
jsonstring = dumps(data)
print jsonstring
print repr(loads(jsonstring))
其他回答
对于Python到JavaScript的日期转换,日期对象需要是特定的ISO格式,即ISO格式或UNIX编号。如果ISO格式缺少一些信息,那么您可以使用Date将其转换为Unix编号。首先解析。此外,日期。parse也适用于React,而new Date可能会触发异常。
如果您有一个没有毫秒的DateTime对象,则需要考虑以下内容。:
var unixDate = Date.parse('2016-01-08T19:00:00')
var desiredDate = new Date(unixDate).toLocaleDateString();
示例日期同样可以是结果中的变量。API调用后的数据对象。
有关以所需格式显示日期的选项(例如,显示较长的工作日),请查看MDN文档。
如果你确定只有Javascript会使用JSON,我更喜欢直接传递Javascript Date对象。
datetime对象上的ctime()方法将返回一个Javascript Date对象可以理解的字符串。
import datetime
date = datetime.datetime.today()
json = '{"mydate":new Date("%s")}' % date.ctime()
Javascript会很乐意使用它作为对象文字,这样就有了内置的Date对象。
简单地这样做:
r = json.dumps(your_json_data, default=str)
your_json_data = json.loads(r)
对于跨语言项目,我发现包含RfC 3339日期的字符串是最好的方法。RfC 3339日期如下所示:
1985-04-12T23:20:50.52Z
我认为大部分格式都是显而易见的。唯一有点不同寻常的可能是结尾的“Z”。它代表GMT/UTC。您还可以添加时区偏移,例如CEST(德国夏季)的+02:00。我个人更喜欢将所有内容都保持UTC格式,直到显示出来。
为了显示、比较和存储,您可以在所有语言中使用字符串格式。如果你需要日期进行计算,很容易将其转换回大多数语言的原生日期对象。
这样生成JSON:
json.dump(datetime.now().strftime('%Y-%m-%dT%H:%M:%SZ'))
不幸的是,Javascript的Date构造函数不接受RfC 3339字符串,但在互联网上有很多可用的解析器。
huTools。hujson试图处理你在Python代码中可能遇到的最常见的编码问题,包括正确处理时区的date/datetime对象。
除了时间戳之外,没有什么要添加到社区wiki答案中!
Javascript使用以下格式:
new Date().toJSON() // "2016-01-08T19:00:00.123Z"
Python端(用于json。转储处理程序,见其他答案):
>>> from datetime import datetime
>>> d = datetime.strptime('2016-01-08T19:00:00.123Z', '%Y-%m-%dT%H:%M:%S.%fZ')
>>> d
datetime.datetime(2016, 1, 8, 19, 0, 0, 123000)
>>> d.isoformat() + 'Z'
'2016-01-08T19:00:00.123000Z'
如果去掉Z,前端框架(如angular)就不能以浏览器本地时区显示日期:
> $filter('date')('2016-01-08T19:00:00.123000Z', 'yyyy-MM-dd HH:mm:ss')
"2016-01-08 20:00:00"
> $filter('date')('2016-01-08T19:00:00.123000', 'yyyy-MM-dd HH:mm:ss')
"2016-01-08 19:00:00"
推荐文章
- 证书验证失败:无法获得本地颁发者证书
- 当使用pip3安装包时,“Python中的ssl模块不可用”
- Babel 6改变了它导出默认值的方式
- 无法切换Python与pyenv
- Python if not == vs if !=
- 如何配置历史记录?
- ES6模板文字可以在运行时被替换(或重用)吗?
- [Vue警告]:找不到元素
- 查询JSON类型内的数组元素
- 如何从scikit-learn决策树中提取决策规则?
- 为什么在Mac OS X v10.9 (Mavericks)的终端中apt-get功能不起作用?
- 可以在setInterval()内部调用clearInterval()吗?
- AngularJS控制器的生命周期是什么?
- 无法读取未定义的属性“msie”- jQuery工具
- 将旋转的xtick标签与各自的xtick对齐