使用Python的strptime解析不带前导零的小时

3 投票
3 回答
4302 浏览
提问于 2025-04-17 15:00

假设你有时间数据,格式是这样的:

a = [..., 800.0, 830.0, 900.0, 930.0, 1000.0, 1030.0, ...]

问题是,小时前面的零缺失了。比如说,00:30 被表示成 3008:00 被表示成 800,而 00:00 被表示成 2400

有没有办法用 strptime 方法把这些数据解析成 time 对象呢?我试着用下面的代码:

hours = [time.strptime(str(int(i)), "%H%M") for i in a]

但是得到了这个错误:

ValueError: unconverted data remains: 0

附注:我使用的是 Python 2.7。

3 个回答

1

如果里面的确是浮点数而不是字符串,你可以这样做:

a=[800., 830., 900., 930., 1000., 1030.]
hours=[time.strptime('{:04.0f}'.format(f), '%H%M') for f in a]

这样做会把小数部分四舍五入,比如 1033.66666 会变成 1034,然后就变成了 10:34 AM

你也可以这样截断小数部分:

[800.0, 830.0, 900.0, 930.0, 1000.0, 1030.0, 1033.3333333, 1033.66666]
hours=[time.strptime(str(f).split('.')[0], '%H%M') for f in a]

根据评论的编辑

如果你的数值超出了范围,你可以这样处理:

a=[800., 830., 900., 930., 1000., 1030., 2400.]
hours=[time.strptime(s,'%H%M') for s in ['{:04.0f}'.format(f) if f <2400 else '0000' for f in a]]

或者,你也可以让你原来的代码这样工作:

[time.strptime(i,'%H%M') for i in[str(int(f)) if f<2400 else '0000' for f in a]]
3

在这种情况下,你可以不使用 strptime() 来提取小时和分钟:

>>> from datetime import time
>>> a = [800., 830., 900., 930., 1000., 1030., 30., 2400.]
>>> [time(*divmod(int(f) % 2400, 100)) for f in a]
[datetime.time(8, 0), 
 datetime.time(8, 30), 
 datetime.time(9, 0), 
 datetime.time(9, 30),
 datetime.time(10, 0),
 datetime.time(10, 30),
 datetime.time(0, 30),
 datetime.time(0, 0)]

如果你出于某种原因想使用 strptime(),你可以用 x % y 简洁地得到所需的格式:

>>> ["%04.0f" % (f % 2400) for f in a]
['0800', '0830', '0900', '0930', '1000', '1030', '0030', '0000']
6

使用 zfill 可以根据需要在数字前面加上零:

hours = [time.strptime(i[:-1].zfill(4), "%H%M") for i in a]

通过使用 i[:-1],我们可以去掉那个烦人的结尾点,接着 .zfill(4) 会在左边加上足够的 0 字符,使数字变成4位数。

示例:

>>> import time
>>> a = ['800.', '830.', '900.', '30.']
>>> [time.strptime(i[:-1].zfill(4), "%H%M") for i in a]
[time.struct_time(tm_year=1900, tm_mon=1, tm_mday=1, tm_hour=8, tm_min=0, tm_sec=0, tm_wday=0, tm_yday=1, tm_isdst=-1), time.struct_time(tm_year=1900, tm_mon=1, tm_mday=1, tm_hour=8, tm_min=30, tm_sec=0, tm_wday=0, tm_yday=1, tm_isdst=-1), time.struct_time(tm_year=1900, tm_mon=1, tm_mday=1, tm_hour=9, tm_min=0, tm_sec=0, tm_wday=0, tm_yday=1, tm_isdst=-1), time.struct_time(tm_year=1900, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=30, tm_sec=0, tm_wday=0, tm_yday=1, tm_isdst=-1)]

如果你的值是浮点数,可以使用 format() 函数 来得到带零的值:

>>> format(800., '04.0f')
'0800'

这样做:

hours = [time.strptime(format(i % 2400, '04.0f'), "%H%M") for i in a]

其中 % 2400 会把你的值规范化到0到2399的范围。

撰写回答