在Google App Engine中将字符串转换为带小数秒的日期时间

19 投票
2 回答
15975 浏览
提问于 2025-04-16 02:19

我需要把一个字符串转换成日期时间对象,还要包括小数秒。但我遇到了各种问题。

通常,我会这样做:

>>> datetime.datetime.strptime(val, "%Y-%m-%dT%H:%M:%S.%f")

但是错误信息和旧文档告诉我,python2.5的strptime不支持%f这个格式...

进一步调查后,我发现App Engine的数据存储不支持小数秒。当我尝试在编辑数据存储实体时,给日期时间字段加上0.5,结果出现了以下错误:

ValueError: unconverted data remains: .5

我怀疑小数秒并不是不支持的...所以这只是数据存储查看器的问题,对吧?

有没有人解决过这个问题?我想使用原生的日期时间对象... 我不想存储UNIX时间戳...

谢谢!


补充:感谢Jacob Oscarson提供的.replace(...)的建议!

有一点需要注意的是,在输入之前要检查nofrag的长度。不同来源对秒的小数精度要求不同。

这里有一个快速的函数,供那些寻找类似东西的人参考:

def strptime(val):
    if '.' not in val:
        return datetime.datetime.strptime(val, "%Y-%m-%dT%H:%M:%S")

    nofrag, frag = val.split(".")
    date = datetime.datetime.strptime(nofrag, "%Y-%m-%dT%H:%M:%S")

    frag = frag[:6]  # truncate to microseconds
    frag += (6 - len(frag)) * '0'  # add 0s
    return date.replace(microsecond=int(frag))

2 个回答

5

这些都是过去的事情了,但在现代,你可以方便地使用 dateutil

from dateutil import parser as DUp

funky_time_str = "1/1/2011 12:51:00.0123 AM"

foo = DUp.parse(funky_time_str)

print foo.timetuple()
# time.struct_time(tm_year=2011, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=51, tm_sec=0, tm_wday=5, tm_yday=1, tm_isdst=-1)

print foo.microsecond
# 12300

print foo
# 2011-01-01 00:51:00.012300

dateutil 支持很多不同的输入格式,而且它可以自动识别这些格式,不需要你自己写规则。

12

解析

即使没有 %f 这种格式支持 datetime.datetime.strptime(),你仍然可以很简单地把它放进一个 datetime.datetime 对象里(这里随机选一个值给你的 val),可以使用 datetime.datetime.replace() 来实现,这在 2.5.5 版本上测试过:

>>> val = '2010-08-06T10:00:14.143896'
>>> nofrag, frag = val.split('.')
>>> nofrag_dt = datetime.datetime.strptime(nofrag, "%Y-%m-%dT%H:%M:%S")
>>> dt = nofrag_dt.replace(microsecond=int(frag))
>>> dt
datetime.datetime(2010, 8, 6, 10, 0, 14, 143896)

现在你已经有了你的 datetime.datetime 对象。

存储

继续阅读 http://code.google.com/appengine/docs/python/datastore/typesandpropertyclasses.html#datetime

我没有看到提到分数(即小数部分)不被支持,所以很可能只是数据存储查看器的问题。文档直接指向 Python 2.5.2 的 datetime 模块文档,而它确实支持分数,只是 strptime 的解析指令中没有 %f。不过,查询分数可能会有点复杂..

撰写回答