我在格式化日期时间时遇到了麻烦。timedelta对象。
这就是我想做的: 我有一个对象列表,对象类的成员之一是显示事件持续时间的timedelta对象。我想以小时:分钟的格式显示这个持续时间。
我尝试了各种方法来做这件事,但我有困难。我目前的方法是为返回小时和分钟的对象在类中添加方法。我可以通过除以time得到小时数。秒乘以3600,四舍五入。我在得到剩余的秒并将其转换为分钟时遇到了麻烦。
顺便说一下,我使用谷歌AppEngine和Django模板来表示。
我在格式化日期时间时遇到了麻烦。timedelta对象。
这就是我想做的: 我有一个对象列表,对象类的成员之一是显示事件持续时间的timedelta对象。我想以小时:分钟的格式显示这个持续时间。
我尝试了各种方法来做这件事,但我有困难。我目前的方法是为返回小时和分钟的对象在类中添加方法。我可以通过除以time得到小时数。秒乘以3600,四舍五入。我在得到剩余的秒并将其转换为分钟时遇到了麻烦。
顺便说一下,我使用谷歌AppEngine和Django模板来表示。
当前回答
我想这样做,所以写了一个简单的函数。它对我来说非常有用,而且非常通用(支持年到微秒,以及任何粒度级别,例如,你可以选择“2天4小时48分钟”和“2天4小时”和“2天4.8小时”等。
def pretty_print_timedelta(t, max_components=None, max_decimal_places=2):
'''
Print a pretty string for a timedelta.
For example datetime.timedelta(days=2, seconds=17280) will be printed as '2 days, 4 hours, 48 minutes'. Setting max_components to e.g. 1 will change this to '2.2 days', where the
number of decimal points can also be set.
'''
time_scales = [timedelta(days=365), timedelta(days=1), timedelta(hours=1), timedelta(minutes=1), timedelta(seconds=1), timedelta(microseconds=1000), timedelta(microseconds=1)]
time_scale_names_dict = {timedelta(days=365): 'year',
timedelta(days=1): 'day',
timedelta(hours=1): 'hour',
timedelta(minutes=1): 'minute',
timedelta(seconds=1): 'second',
timedelta(microseconds=1000): 'millisecond',
timedelta(microseconds=1): 'microsecond'}
count = 0
txt = ''
first = True
for scale in time_scales:
if t >= scale:
count += 1
if count == max_components:
n = t / scale
else:
n = int(t / scale)
t -= n*scale
n_txt = str(round(n, max_decimal_places))
if n_txt[-2:]=='.0': n_txt = n_txt[:-2]
txt += '{}{} {}{}'.format('' if first else ', ', n_txt, time_scale_names_dict[scale], 's' if n>1 else '', )
if first:
first = False
if len(txt) == 0:
txt = 'none'
return txt
其他回答
我使用人类友好的python库来做这件事,它工作得非常好。
import humanfriendly
from datetime import timedelta
delta = timedelta(seconds = 321)
humanfriendly.format_timespan(delta)
'5 minutes and 21 seconds'
网址:https://pypi.org/project/humanfriendly/
请检查这个函数-它将timedelta对象转换为字符串'HH:MM:SS'
def format_timedelta(td):
hours, remainder = divmod(td.total_seconds(), 3600)
minutes, seconds = divmod(remainder, 60)
hours, minutes, seconds = int(hours), int(minutes), int(seconds)
if hours < 10:
hours = '0%s' % int(hours)
if minutes < 10:
minutes = '0%s' % minutes
if seconds < 10:
seconds = '0%s' % seconds
return '%s:%s:%s' % (hours, minutes, seconds)
可能:
>>> import datetime
>>> dt0 = datetime.datetime(1,1,1)
>>> td = datetime.timedelta(minutes=34, hours=12, seconds=56)
>>> (dt0+td).strftime('%X')
'12:34:56'
>>> (dt0+td).strftime('%M:%S')
'34:56'
>>> (dt0+td).strftime('%H:%M')
'12:34'
>>>
一个班轮。由于timedelta不提供datetime的strftime,所以将timedelta带回datetime,并使用stftime。
这不仅可以实现OP要求的格式Hours:Minutes,现在您可以利用datetime的strftime的全部格式化功能,如果您的需求更改为另一种表示形式。
import datetime
td = datetime.timedelta(hours=2, minutes=10, seconds=5)
print(td)
print(datetime.datetime.strftime(datetime.datetime.strptime(str(td), "%H:%M:%S"), "%H:%M"))
Output:
2:10:05
02:10
这也解决了时间增量被格式化为H:MM:SS而不是HH:MM:SS的字符串的烦恼,这导致了我的这个问题,以及我分享的解决方案。
我有一个函数:
def period(delta, pattern):
d = {'d': delta.days}
d['h'], rem = divmod(delta.seconds, 3600)
d['m'], d['s'] = divmod(rem, 60)
return pattern.format(**d)
例子:
>>> td = timedelta(seconds=123456789)
>>> period(td, "{d} days {h}:{m}:{s}")
'1428 days 21:33:9'
>>> period(td, "{h} hours, {m} minutes and {s} seconds, {d} days")
'21 hours, 33 minutes and 9 seconds, 1428 days'