我在格式化日期时间时遇到了麻烦。timedelta对象。
这就是我想做的: 我有一个对象列表,对象类的成员之一是显示事件持续时间的timedelta对象。我想以小时:分钟的格式显示这个持续时间。
我尝试了各种方法来做这件事,但我有困难。我目前的方法是为返回小时和分钟的对象在类中添加方法。我可以通过除以time得到小时数。秒乘以3600,四舍五入。我在得到剩余的秒并将其转换为分钟时遇到了麻烦。
顺便说一下,我使用谷歌AppEngine和Django模板来表示。
我在格式化日期时间时遇到了麻烦。timedelta对象。
这就是我想做的: 我有一个对象列表,对象类的成员之一是显示事件持续时间的timedelta对象。我想以小时:分钟的格式显示这个持续时间。
我尝试了各种方法来做这件事,但我有困难。我目前的方法是为返回小时和分钟的对象在类中添加方法。我可以通过除以time得到小时数。秒乘以3600,四舍五入。我在得到剩余的秒并将其转换为分钟时遇到了麻烦。
顺便说一下,我使用谷歌AppEngine和Django模板来表示。
当前回答
下面是一个stringify timedelta.total_seconds()的函数。它在python2和python3中工作。
def strf_interval(seconds):
days, remainder = divmod(seconds, 86400)
hours, remainder = divmod(remainder, 3600)
minutes, seconds = divmod(remainder, 60)
return '{} {} {} {}'.format(
"" if int(days) == 0 else str(int(days)) + ' days',
"" if int(hours) == 0 else str(int(hours)) + ' hours',
"" if int(minutes) == 0 else str(int(minutes)) + ' mins',
"" if int(seconds) == 0 else str(int(seconds)) + ' secs'
)
示例输出:
>>> print(strf_interval(1))
1 secs
>>> print(strf_interval(100))
1 mins 40 secs
>>> print(strf_interval(1000))
16 mins 40 secs
>>> print(strf_interval(10000))
2 hours 46 mins 40 secs
>>> print(strf_interval(100000))
1 days 3 hours 46 mins 40 secs
其他回答
我知道这是一个老问题,但我使用datetime.utcfromtimestamp()来解决这个问题。它接受秒数并返回一个datetime,该datetime可以像任何其他datetime一样格式化。
duration = datetime.utcfromtimestamp(end - begin)
print duration.strftime('%H:%M')
只要您停留在时间部分的合法范围内,这就应该工作,即它不会返回1234:35,因为小时<= 23。
如您所知,您可以通过访问.seconds属性从timedelta对象中获得total_seconds。
Python提供了内置函数divmod(),它允许:
s = 13420
hours, remainder = divmod(s, 3600)
minutes, seconds = divmod(remainder, 60)
print('{:02}:{:02}:{:02}'.format(int(hours), int(minutes), int(seconds)))
# result: 03:43:40
或者你可以结合使用模和减法来转换小时和余数:
# arbitrary number of seconds
s = 13420
# hours
hours = s // 3600
# remaining seconds
s = s - (hours * 3600)
# minutes
minutes = s // 60
# remaining seconds
seconds = s - (minutes * 60)
# total time
print('{:02}:{:02}:{:02}'.format(int(hours), int(minutes), int(seconds)))
# result: 03:43:40
我想这样做,所以写了一个简单的函数。它对我来说非常有用,而且非常通用(支持年到微秒,以及任何粒度级别,例如,你可以选择“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/
谢谢大家的帮助。我把你的很多想法放在一起,让我知道你的想法。
我像这样在类中添加了两个方法:
def hours(self):
retval = ""
if self.totalTime:
hoursfloat = self.totalTime.seconds / 3600
retval = round(hoursfloat)
return retval
def minutes(self):
retval = ""
if self.totalTime:
minutesfloat = self.totalTime.seconds / 60
hoursAsMinutes = self.hours() * 60
retval = round(minutesfloat - hoursAsMinutes)
return retval
在我的django中,我使用了这个(sum是对象,它在一个字典中):
<td>{{ sum.0 }}</td>
<td>{{ sum.1.hours|stringformat:"d" }}:{{ sum.1.minutes|stringformat:"#02.0d" }}</td>