是否可以将datetime转换为可读的JSON格式(可以从javascript使用)?目前jsonpickle仅为datetime提供二进制编码值。
答案 0 :(得分:4)
这里有几个问题:
首先,请不要在时区中流量不知道日期时间对象。你会感到痛苦,不是今天,也许不是明天,而是某一天。你可以从别人的错误中学习(我的),或者你可以学到很多困难。据我所知,Python允许你创建没有时区的日期时间对象是一个错误。
其次,strptime不处理时区!所以你做了正确的事情,然后你以某种格式写了你的日期,并想把它读回来,并且kablooey,你得到'%z格式错误的字符串'。 GRR。
使用iso8601库来解析ISO8601日期时间字符串。时区处理。
第三,jsonpickle没有清楚地记录如何滚动你自己的DatetimeHandler。所以,是的,你只是想要一些易读的东西,你发送到Javascript或其他什么?上面的解决方案没问题。你想要的东西是清晰的,但你也想在某些时候把它拉回到Python中?嗯,比较棘手。
这是一个提示:当您继承库以扩展其功能时,请仔细查看您正在扩展的超类。
我会以不同的方式编写DatetimeHandler。但是下面的作品,包含了我在这个主题上所有来之不易的智慧。哎哟。
import pytz
import jsonpickle
import iso8601
from datetime import datetime
class Blah(object):
def __init__(self, blah):
self.datetime = datetime.now(pytz.utc)
self.blah = blah
def to_json(self):
return jsonpickle.encode(self)
@classmethod
def from_json(cls, json_str):
return jsonpickle.decode(json_str)
class DatePickleISO8601(jsonpickle.handlers.DatetimeHandler):
def flatten(self, obj, data):
pickler = self.context
if not pickler.unpicklable:
return unicode(obj)
cls, args = obj.__reduce__()
flatten = pickler.flatten
payload = obj.isoformat()
args = [payload] + [flatten(i, reset=False) for i in args[1:]]
data['__reduce__'] = (flatten(cls, reset=False), args)
return data
def restore(self, data):
cls, args = data['__reduce__']
unpickler = self.context
restore = unpickler.restore
cls = restore(cls, reset=False)
value = iso8601.parse_date(args[0])
return value
jsonpickle.handlers.registry.register(datetime, DatePickleISO8601)
答案 1 :(得分:2)
使用当前版本的jsonpickle(从今天的pip获得),如果设置不可点击为false,那么似乎可以正常使用编码:
>>> import jsonpickle
>>> from datetime import datetime
>>> jsonpickle.encode(datetime.now(), unpicklable=False)
'"2014-05-25 20:24:30.357299"'
然而,根据ECMAScript v5规范,您的技巧可用于生成ISO 8601 format,这可能更合适:
>>> class DatetimeHandler(jsonpickle.handlers.BaseHandler):
... def flatten(self, obj, data):
... return obj.isoformat()
...
>>> jsonpickle.handlers.registry.register(datetime, DatetimeHandler)
>>> jsonpickle.encode(datetime.now(), unpicklable=False)
'"2014-05-25T20:31:30.422826"'
答案 2 :(得分:1)
经过一些试验和错误后,我提出了以下解决方案:
class DatetimeHandler(jsonpickle.handlers.BaseHandler):
def flatten(self, obj, data):
return obj.strftime('%Y-%m-%d %H:%M:%S.%f')
jsonpickle.handlers.registry.register(datetime, DatetimeHandler)
encoded_datetime = jsonpickle.encode(datetime.now())
print(encoded_datetime)
decode_datetime = jsonpickle.decode(encoded_datetime)
print(decode_datetime)