这里有一个通用的函数,可以将一个 timedelta
对象或常规数字(以秒或分钟等形式)转换为格式化良好的字符串。 我使用mpounsett的绝妙答案对重复问题进行了改进,使其更具灵活性,易读性和文档性。
您会发现它是迄今为止最灵活的答案,因为它允许您:
- 即时自定义字符串格式,而不是硬编码它。
- 轻松省略某些时间间隔(请参见下面的示例)。
函数:
from string import Formatter
from datetime import timedelta
def strfdelta(tdelta, fmt='{D:02}d {H:02}h {M:02}m {S:02}s', inputtype='timedelta'):
"""Convert a datetime.timedelta object or a regular number to a custom-
formatted string, just like the stftime() method does for datetime.datetime
objects.
The fmt argument allows custom formatting to be specified. Fields can
include seconds, minutes, hours, days, and weeks. Each field is optional.
Some examples:
'{D:02}d {H:02}h {M:02}m {S:02}s' --> '05d 08h 04m 02s' (default)
'{W}w {D}d {H}:{M:02}:{S:02}' --> '4w 5d 8:04:02'
'{D:2}d {H:2}:{M:02}:{S:02}' --> ' 5d 8:04:02'
'{H}h {S}s' --> '72h 800s'
The inputtype argument allows tdelta to be a regular number instead of the
default, which is a datetime.timedelta object. Valid inputtype strings:
's', 'seconds',
'm', 'minutes',
'h', 'hours',
'd', 'days',
'w', 'weeks'
"""
if inputtype == 'timedelta':
remainder = int(tdelta.total_seconds())
elif inputtype in ['s', 'seconds']:
remainder = int(tdelta)
elif inputtype in ['m', 'minutes']:
remainder = int(tdelta)*60
elif inputtype in ['h', 'hours']:
remainder = int(tdelta)*3600
elif inputtype in ['d', 'days']:
remainder = int(tdelta)*86400
elif inputtype in ['w', 'weeks']:
remainder = int(tdelta)*604800
f = Formatter()
desired_fields = [field_tuple[1] for field_tuple in f.parse(fmt)]
possible_fields = ('W', 'D', 'H', 'M', 'S')
constants = {'W': 604800, 'D': 86400, 'H': 3600, 'M': 60, 'S': 1}
values = {}
for field in possible_fields:
if field in desired_fields and field in constants:
values[field], remainder = divmod(remainder, constants[field])
return f.format(fmt, **values)
演示:
>>> td = timedelta(days=2, hours=3, minutes=5, seconds=8, microseconds=340)
>>> print strfdelta(td)
02d 03h 05m 08s
>>> print strfdelta(td, '{D}d {H}:{M:02}:{S:02}')
2d 3:05:08
>>> print strfdelta(td, '{D:2}d {H:2}:{M:02}:{S:02}')
2d 3:05:08
>>> print strfdelta(td, '{H}h {S}s')
51h 308s
>>> print strfdelta(12304, inputtype='s')
00d 03h 25m 04s
>>> print strfdelta(620, '{H}:{M:02}', 'm')
10:20
>>> print strfdelta(49, '{D}d {H}h', 'h')
2d 1h
datetime.utcfromtimestamp()
,您就可以在一定程度上实现。请参见下面的我的回答。 - sjngmtimedelta
的__str__
相当不错,与__repr__
(即针对人类!)相反。例如:datetime.timedelta(minutes=6, seconds=41) * 2618 / 48
会得到datetime.timedelta(seconds=21871, microseconds=208333)
,但是str(datetime.timedelta(minutes=6, seconds=41) * 2618 / 48)
会得到'6:04:31.208333'
,这相当容易阅读。 - Tomasz Gandorimport
(https://dev59.com/6HRB5IYBdhLWcg3wuZQ1#WqMtoYgBc1ULPQZFDMWQ)就像我自己建议的那样,会有一些影响:性能下降(strptime 慢了 2 倍),不兼容性问题出现(时区模块崩溃)。 - NameOfTheRose