我在格式化日期时间时遇到了麻烦。timedelta对象。
这就是我想做的: 我有一个对象列表,对象类的成员之一是显示事件持续时间的timedelta对象。我想以小时:分钟的格式显示这个持续时间。
我尝试了各种方法来做这件事,但我有困难。我目前的方法是为返回小时和分钟的对象在类中添加方法。我可以通过除以time得到小时数。秒乘以3600,四舍五入。我在得到剩余的秒并将其转换为分钟时遇到了麻烦。
顺便说一下,我使用谷歌AppEngine和Django模板来表示。
我在格式化日期时间时遇到了麻烦。timedelta对象。
这就是我想做的: 我有一个对象列表,对象类的成员之一是显示事件持续时间的timedelta对象。我想以小时:分钟的格式显示这个持续时间。
我尝试了各种方法来做这件事,但我有困难。我目前的方法是为返回小时和分钟的对象在类中添加方法。我可以通过除以time得到小时数。秒乘以3600,四舍五入。我在得到剩余的秒并将其转换为分钟时遇到了麻烦。
顺便说一下,我使用谷歌AppEngine和Django模板来表示。
当前回答
from django.utils.translation import ngettext
def localize_timedelta(delta):
ret = []
num_years = int(delta.days / 365)
if num_years > 0:
delta -= timedelta(days=num_years * 365)
ret.append(ngettext('%d year', '%d years', num_years) % num_years)
if delta.days > 0:
ret.append(ngettext('%d day', '%d days', delta.days) % delta.days)
num_hours = int(delta.seconds / 3600)
if num_hours > 0:
delta -= timedelta(hours=num_hours)
ret.append(ngettext('%d hour', '%d hours', num_hours) % num_hours)
num_minutes = int(delta.seconds / 60)
if num_minutes > 0:
ret.append(ngettext('%d minute', '%d minutes', num_minutes) % num_minutes)
return ' '.join(ret)
这将产生:
>>> from datetime import timedelta
>>> localize_timedelta(timedelta(days=3660, minutes=500))
'10 years 10 days 8 hours 20 minutes'
其他回答
您可以使用str()将timedelta转换为字符串。这里有一个例子:
import datetime
start = datetime.datetime(2009,2,10,14,00)
end = datetime.datetime(2009,2,10,16,00)
delta = end-start
print(str(delta))
# prints 2:00:00
我的datetime。Timedelta对象的时间大于一天。这是一个更深层次的问题。以上所有讨论都假设时间不超过一天。timedelta实际上是一个由日、秒和微秒组成的元组。上面的讨论应该使用td。秒,因为乔做了,但如果你有天,它不包括在秒值。
我得到2个日期时间和打印天和小时之间的时间跨度。
span = currentdt - previousdt
print '%d,%d\n' % (span.days,span.seconds/3600)
我想这样做,所以写了一个简单的函数。它对我来说非常有用,而且非常通用(支持年到微秒,以及任何粒度级别,例如,你可以选择“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
def seconds_to_time_left_string(total_seconds):
s = int(total_seconds)
years = s // 31104000
if years > 1:
return '%d years' % years
s = s - (years * 31104000)
months = s // 2592000
if years == 1:
r = 'one year'
if months > 0:
r += ' and %d months' % months
return r
if months > 1:
return '%d months' % months
s = s - (months * 2592000)
days = s // 86400
if months == 1:
r = 'one month'
if days > 0:
r += ' and %d days' % days
return r
if days > 1:
return '%d days' % days
s = s - (days * 86400)
hours = s // 3600
if days == 1:
r = 'one day'
if hours > 0:
r += ' and %d hours' % hours
return r
s = s - (hours * 3600)
minutes = s // 60
seconds = s - (minutes * 60)
if hours >= 6:
return '%d hours' % hours
if hours >= 1:
r = '%d hours' % hours
if hours == 1:
r = 'one hour'
if minutes > 0:
r += ' and %d minutes' % minutes
return r
if minutes == 1:
r = 'one minute'
if seconds > 0:
r += ' and %d seconds' % seconds
return r
if minutes == 0:
return '%d seconds' % seconds
if seconds == 0:
return '%d minutes' % minutes
return '%d minutes and %d seconds' % (minutes, seconds)
for i in range(10):
print pow(8, i), seconds_to_time_left_string(pow(8, i))
Output:
1 1 seconds
8 8 seconds
64 one minute and 4 seconds
512 8 minutes and 32 seconds
4096 one hour and 8 minutes
32768 9 hours
262144 3 days
2097152 24 days
16777216 6 months
134217728 4 years
一个班轮。由于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的字符串的烦恼,这导致了我的这个问题,以及我分享的解决方案。