我在格式化日期时间时遇到了麻烦。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.utcfromtimestamp()来解决这个问题。它接受秒数并返回一个datetime,该datetime可以像任何其他datetime一样格式化。

duration = datetime.utcfromtimestamp(end - begin)
print duration.strftime('%H:%M')

只要您停留在时间部分的合法范围内,这就应该工作,即它不会返回1234:35,因为小时<= 23。

>>> str(datetime.timedelta(hours=10.56))
10:33:36

>>> td = datetime.timedelta(hours=10.505) # any timedelta object
>>> ':'.join(str(td).split(':')[:2])
10:30

将timedelta对象传递给str()函数调用的格式化代码与输入print td相同。因为你不想要秒,我们可以用冒号分隔字符串(3部分),然后只用前2部分把它重新组合在一起。

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'

如您所知,您可以通过访问.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