Formate timedelta para string

275

Estou tendo problemas para formatar um datetime.timedeltaobjeto.

Aqui está o que estou tentando fazer: Eu tenho uma lista de objetos e um dos membros da classe do objeto é um objeto timedelta que mostra a duração de um evento. Gostaria de exibir essa duração no formato de horas: minutos.

Eu tentei uma variedade de métodos para fazer isso e estou tendo dificuldades. Minha abordagem atual é adicionar métodos à classe para meus objetos que retornam horas e minutos. Posso obter as horas dividindo o timedelta.seconds por 3600 e arredondando-o. Estou tendo problemas para obter os segundos restantes e converter isso em minutos.

A propósito, estou usando o Google AppEngine com Django Templates para apresentação.

mawcs
fonte
44
Seria bom se timedelta tivesse um equivalente ao método strftime ().
JS.
@JS. Bem, você pode um pouco se você usar datetime.utcfromtimestamp(). Veja minha resposta abaixo.
sjngm
@JS. - 100% concorda. Então, __str__de timedeltaé bastante decente, em oposição a __repr__(isto é - para humanos!). Por exemplo: datetime.timedelta(minutes=6, seconds=41) * 2618 / 48datetime.timedelta(seconds=21871, microseconds=208333), mas str(datetime.timedelta(minutes=6, seconds=41) * 2618 / 48)dá o '6:04:31.208333'que é razoavelmente bom de ler.
Tomasz Gandor 14/01

Respostas:

213

Você pode apenas converter o timedelta em uma string com str (). Aqui está um exemplo:

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
Parand
fonte
13
É mais como chamar o método str () com timedelta como argumento.
31119 joeforker
12
Você não precisa da chamada str, ela será feita automaticamente por impressão.
Zitrax 14/02
5
@Zitrax, mas é necessário se você deseja concatenar o delta com outra string. Por exemploprint 'some thing ' + str(delta)
Plinio.Santos
13
E necessário quando o tipo de dados é definido como 'datetime.timedelta' e você o está usando assim ConvertDuration=datetime.timedelta(milliseconds=int(254459)), basta usar split para tirar os microssegundos de folga. De 0: 03: 43.765000 Eu consigo 0:03:43 simplesmente executandoTotalDuration=str(ConvertDuration).split('.', 2)[0]
DarkXDroid 8/15
16
Isso pode imprimir o delta como uma sequência, mas não o formata como o OP solicitado.
Dannid
187

Como você sabe, você pode obter o total_seconds de um objeto timedelta acessando o .secondsatributo

Python fornece a função interna divmod()que permite:

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

ou você pode converter para horas e o restante usando uma combinação de módulo e subtração:

# 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
John Fouhy
fonte
5
Para timedeltas negativos, você deve avaliar o sinal primeiro e depois avaliar abs(s).
mbarkhau
27
Observe que você pode realmente querer usar '%d:%02d:%02d'para ter zeros à esquerda na string de saída.
ShinNoNoir
12
para python 2,7 e maiores .total_seconds uso () Método
sk8asd123
27
Não use .secondsse a diferença puder ser negativa ou superior a 24 horas (o .secondsatributo ignora .days). Use .total_seconds()ou seu analógico.
JFS
Para diferenças positivas, estou reimplementando isso de tempos em tempos. Obrigado por apenas ter que procurar desta vez :)
Lobo
59
>>> 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

Passar o timedeltaobjeto para a str()função chama o mesmo código de formatação usado se simplesmente digitarmos print td. Como você não deseja os segundos, podemos dividir a sequência por dois pontos (3 partes) e juntá-la novamente apenas com as 2 primeiras partes.

joeforker
fonte
Obrigado pela sua resposta joeforker, mas não tenho certeza se entendi sua resposta. Estou recebendo um delta de tempo por meio de data e hora - data e hora. Eu não sei as horas. Além disso, parece que seu exemplo inclui segundos. Como eu o removia?
mawcs
1
Não importa onde você obtenha o objeto timedelta, ele será formatado da mesma forma.
31119 joeforker
9
Se for mais de um dia, será formatado como, por exemplo, "4 dias, 8:00" após o processamento da divisão / junção.
31119 joeforker
4
str(my_timedelta)funciona mal para números negativos
Catskul 17/05
2
Mostra também os dias em que> 24 horas, por exemplo, '4 dias, 18: 48: 22.330000'. Muitos métodos recomendados aqui não.
Alexei Martianov
47
def td_format(td_object):
    seconds = int(td_object.total_seconds())
    periods = [
        ('year',        60*60*24*365),
        ('month',       60*60*24*30),
        ('day',         60*60*24),
        ('hour',        60*60),
        ('minute',      60),
        ('second',      1)
    ]

    strings=[]
    for period_name, period_seconds in periods:
        if seconds > period_seconds:
            period_value , seconds = divmod(seconds, period_seconds)
            has_s = 's' if period_value > 1 else ''
            strings.append("%s %s%s" % (period_value, period_name, has_s))

    return ", ".join(strings)
Adam Jacob Muller
fonte
3
Muito bom, eu sugeriria mudar if seconds > period_seconds:para if seconds >= period_seconds:no entanto.
CBenni
1
Isso retorna cadeias vazias para timedeltas negativos, não tenho certeza se isso é pretendido?
Dirk
31

Eu pessoalmente uso a humanizebiblioteca para isso:

>>> import datetime
>>> humanize.naturalday(datetime.datetime.now())
'today'
>>> humanize.naturalday(datetime.datetime.now() - datetime.timedelta(days=1))
'yesterday'
>>> humanize.naturalday(datetime.date(2007, 6, 5))
'Jun 05'
>>> humanize.naturaldate(datetime.date(2007, 6, 5))
'Jun 05 2007'
>>> humanize.naturaltime(datetime.datetime.now() - datetime.timedelta(seconds=1))
'a second ago'
>>> humanize.naturaltime(datetime.datetime.now() - datetime.timedelta(seconds=3600))
'an hour ago'

Obviamente, isso não fornece exatamente a resposta que você estava procurando (que é, de fato,str(timeA - timeB) mas eu descobri que, depois que você passa algumas horas, a tela fica rapidamente ilegível. humanizeTem suporte para valores muito maiores que são legível por humanos e também está bem localizada.

É inspirado no contrib.humanizemódulo do Django , aparentemente, então, como você está usando o Django, você provavelmente deveria usá-lo.

anarcat
fonte
2
Bom, + 1 Embora: humanize.naturaldelta (pd.Timedelta ('- 10sec')) -> '10 segundos ': S ...
ntg
2
bem, é um delta de 10 segundos . :) se você quer a hora , naturaltimeé o que você quer usar.
Anarcat
28

Ele já possui um objeto timedelta, por que não usar seu método interno total_seconds () para convertê-lo em segundos e usar divmod () para obter horas e minutos?

hours, remainder = divmod(myTimeDelta.total_seconds(), 3600)
minutes, seconds = divmod(remainder, 60)

# Formatted only for hours and minutes as requested
print '%s:%s' % (hours, minutes)

Isso funciona independentemente do delta de tempo ter dias ou anos.

Bill Kidd
fonte
23

Aqui está uma função de uso geral para converter um timedeltaobjeto ou um número regular (na forma de segundos ou minutos, etc.) em uma sequência bem formatada. Tomei resposta fantástica de mpounsett sobre uma questão duplicado, fez dele um pouco mais flexível, melhor legibilidade e documentação adicional.

Você descobrirá que é a resposta mais flexível aqui até agora, pois permite:

  1. Personalize o formato da string rapidamente, em vez de ser codificado.
  2. Deixe alguns intervalos de tempo sem problemas (veja os exemplos abaixo).

Função:

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'
    """

    # Convert tdelta to integer seconds.
    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)

Demo:

>>> 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
MarredCheese
fonte
Muito bom, código limpo! Gostaria de saber como esse código pode ser expandido para lidar com os últimos segundos restantes fracionários no formatador ...
kfmfe04
17

Sei que essa é uma pergunta antiga respondida, mas uso datetime.utcfromtimestamp()para isso. Leva o número de segundos e retorna um datetimeque pode ser formatado como qualquer outro datetime.

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

Contanto que você permaneça nos intervalos legais para os períodos de tempo, isso deve funcionar, ou seja, não retorna 1234: 35, pois as horas são <= 23.

sjngm
fonte
2
você deve usar em seu print timedelta(seconds=end - begin)lugar.
JFS
@JFSebastian Então você teria que preencher as horas manualmente com zeros à esquerda.
sjngm
Não vejo nada sobre preenchimento na pergunta. Use .zfill(8)se você precisar.
Jfs #
1
Precisa de uma chamada .total_seconds (): >>> datetime.utcfromtimestamp ((t2-t1) .total_seconds ()). Strftime ("% H:% M:% S") <<< >>> '00: 00: 05 '
cagney
2
Eu prefiro muito esta solução, que permite controlar a formatação. Note que você também pode usar o str formatador diretamente assim: "{0:% H}: {0:% M}" formato (duração).
dedos
15

O interlocutor deseja um formato melhor do que o típico:

  >>> import datetime
  >>> datetime.timedelta(seconds=41000)
  datetime.timedelta(0, 41000)
  >>> str(datetime.timedelta(seconds=41000))
  '11:23:20'
  >>> str(datetime.timedelta(seconds=4102.33))
  '1:08:22.330000'
  >>> str(datetime.timedelta(seconds=413302.33))
  '4 days, 18:48:22.330000'

Então, realmente existem dois formatos, um em que os dias são 0 e são deixados de fora, e outro em que há o texto "n days, h: m: s". Mas, os segundos podem ter frações e não há zeros à esquerda nas impressões, portanto, as colunas ficam confusas.

Aqui está minha rotina, se você gosta:

def printNiceTimeDelta(stime, etime):
    delay = datetime.timedelta(seconds=(etime - stime))
    if (delay.days > 0):
        out = str(delay).replace(" days, ", ":")
    else:
        out = "0:" + str(delay)
    outAr = out.split(':')
    outAr = ["%02d" % (int(float(x))) for x in outAr]
    out   = ":".join(outAr)
    return out

isso retorna a saída como dd: hh: mm: ss formato:

00:00:00:15
00:00:00:19
02:01:31:40
02:01:32:22

Pensei em adicionar anos a isso, mas isso é deixado como um exercício para o leitor, pois a saída é segura em mais de 1 ano:

>>> str(datetime.timedelta(seconds=99999999))
'1157 days, 9:46:39'
Kevin J. Rice
fonte
15

Eu consideraria seriamente a abordagem de Occam's Razor aqui:

td = str(timedelta).split('.')[0]

Isso retorna uma string sem os microssegundos

Se você deseja gerar novamente o objeto datetime.timedelta, faça o seguinte:

h,m,s = re.split(':', td)
new_delta = datetime.timedelta(hours=int(h),minutes=int(m),seconds=int(s))

2 anos depois, adoro esse idioma!

Pyrotherm
fonte
5
Isso não cobre os dias #
Waschbaer
13

Meus datetime.timedeltaobjetos foram maiores que um dia. Então, aqui está outro problema. Toda a discussão acima assume menos de um dia. A timedeltaé na verdade uma tupla de dias, segundos e microssegundos. A discussão acima deve usar td.secondscomo joe, mas se você tiver dias, NÃO será incluído no valor de segundos.

Estou tendo um período de tempo entre duas datas e a impressão de dias e horas.

span = currentdt - previousdt
print '%d,%d\n' % (span.days,span.seconds/3600)
Alex L
fonte
Esta é a solução à prova do futuro.
Jibin 22/08
11

Eu usei a humanfriendlybiblioteca python para fazer isso, funciona muito bem.

import humanfriendly
from datetime import timedelta
delta = timedelta(seconds = 321)
humanfriendly.format_timespan(delta)

'5 minutes and 21 seconds'

Disponível em https://pypi.org/project/humanfriendly/

Dhiraj Gupta
fonte
7

Seguindo o valor de exemplo de Joe acima, eu usaria o operador aritmético de módulo, assim:

td = datetime.timedelta(hours=10.56)
td_str = "%d:%d" % (td.seconds/3600, td.seconds%3600/60)

Observe que a divisão inteira no Python é arredondada por padrão; se você quiser ser mais explícito, use math.floor () ou math.ceil () conforme apropriado.

UltraNurd
fonte
O timedelta já sabe como se formatar, como em 'print some_timedelta'.
31119 joeforker
Sim, mas não pode aceitar uma string de formato arbitrário, que é o que Michael estava perguntando. Embora agora que eu penso sobre isso, o mod de 3600 divisões faça a suposição horas-segundos que causa problemas em segundos bissextos.
UltraNurd
Sim, mas ele não quer uma string de formato arbitrário, ele quer quase exatamente o comportamento padrão.
31119 joeforker
2
Não se esqueça // para truncar divisão em Python 3000
joeforker
3
+1, mas por que você não edita a resposta para usar //? Eu também sugeriria usar em td.total_seconds()vez de .secondsfazê-lo funcionar por intervalos> 1 dia.
Antony Hatchkins
4
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
Veselin Penev
fonte
Você escreveu este? Quanto você testou?
Thomas Ahle 04/12/2013
Estou usando esse código no meu projeto chamado datahaven.net . Funciona muito bem. Você viu algum erro?
Veselin Penev
É sempre bom se você pode fornecer um pouco de informação com uma resposta pesada desse código :) Como um exemplo de como funciona, possíveis pontos fortes e fracos.
Thomas Ahle 12/12
1
Oh. Certo!. Adicionado um exemplo para você. :-)
Veselin Penev
Super :) Também aviso que o timedeltaobjeto tem os campos days, secondse microsecondspela documentação.
Thomas Ahle
4

Eu tive um problema semelhante com a saída do cálculo de horas extras no trabalho. O valor sempre deve aparecer em HH: MM, mesmo quando for maior que um dia e o valor puder ficar negativo. Combinei algumas das soluções mostradas e talvez alguém ache essa solução útil. Percebi que, se o valor timedelta for negativo, a maioria das soluções mostradas com o método divmod não funcionará imediatamente:

def td2HHMMstr(td):
  '''Convert timedelta objects to a HH:MM string with (+/-) sign'''
  if td < datetime.timedelta(seconds=0):
    sign='-'
    td = -td
  else:
    sign = ''
  tdhours, rem = divmod(td.total_seconds(), 3600)
  tdminutes, rem = divmod(rem, 60)
  tdstr = '{}{:}:{:02d}'.format(sign, int(tdhours), int(tdminutes))
  return tdstr

timedelta para HH: MM string:

td2HHMMstr(datetime.timedelta(hours=1, minutes=45))
'1:54'

td2HHMMstr(datetime.timedelta(days=2, hours=3, minutes=2))
'51:02'

td2HHMMstr(datetime.timedelta(hours=-3, minutes=-2))
'-3:02'

td2HHMMstr(datetime.timedelta(days=-35, hours=-3, minutes=-2))
'-843:02'
nealtz
fonte
4
import datetime
hours = datetime.timedelta(hours=16, minutes=30)
print((datetime.datetime(1,1,1) + hours).strftime('%H:%M'))
SleX
fonte
2
em 3,7 I get AttributeError: objeto 'datetime.timedelta' tem nenhum atributo 'strftime'
qubodup
4

Um filtro de modelo direto para esse problema. A função interna int () nunca é arredondada. F-Strings (ie f '') requerem python 3.6.

@app_template_filter()
def diffTime(end, start):
    diff = (end - start).total_seconds()
    d = int(diff / 86400)
    h = int((diff - (d * 86400)) / 3600)
    m = int((diff - (d * 86400 + h * 3600)) / 60)
    s = int((diff - (d * 86400 + h * 3600 + m *60)))
    if d > 0:
        fdiff = f'{d}d {h}h {m}m {s}s'
    elif h > 0:
        fdiff = f'{h}h {m}m {s}s'
    elif m > 0:
        fdiff = f'{m}m {s}s'
    else:
        fdiff = f'{s}s'
    return fdiff
Patrick
fonte
3
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)

Isso produzirá:

>>> from datetime import timedelta
>>> localize_timedelta(timedelta(days=3660, minutes=500))
'10 years 10 days 8 hours 20 minutes'
Artem Vasilev
fonte
A mais arrumada na minha opinião, em termos de duração e do que ela cobre #
Dici
1

Por favor, verifique esta função - ele converte o objeto timedelta na string '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)
MobilePro.pl
fonte
1

Um forro. Como o timedeltas não oferece o tempo de espera do horário de hora de datetime, traga o timedelta de volta para um horário de data e use stftime.

Isso pode não apenas atingir o formato solicitado pelo OP Horas: minutos, agora você pode aproveitar todo o poder de formatação do tempo de transmissão da data e hora, caso seus requisitos mudem para outra representação.

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

Isso também resolve o aborrecimento que timedeltas são formatados em strings como H: MM: SS em vez de HH: MM: SS, o que me leva a esse problema e à solução que compartilhei.

Bill Gale
fonte
0

Se você já possui um objeto timedelta, basta convertê-lo em string. Remova os três últimos caracteres da sequência e imprima. Isso truncará a parte dos segundos e imprimirá o restante no formato Horas: Minutos.

t = str(timedeltaobj) 

print t[:-3]
Sima
fonte
O -3 não funciona, melhor uso print t.split('.')[0]
EvgenyKolyakov
0

Se você tem IPythonem seus pacotes (você deveria), ele tem (até agora, de qualquer maneira) um formatador muito bom por durações (em segundos flutuantes). Isso é usado em vários lugares, por exemplo, pela %%timemagia da célula. Gosto do formato que produz por breves períodos:

>>> from IPython.core.magics.execution import _format_time
>>> 
>>> for v in range(-9, 10, 2):
...     dt = 1.25 * 10**v
...     print(_format_time(dt))

1.25 ns
125 ns
12.5 µs
1.25 ms
125 ms
12.5 s
20min 50s
1d 10h 43min 20s
144d 16h 13min 20s
14467d 14h 13min 20s
Pierre D
fonte
-3
t1 = datetime.datetime.strptime(StartTime, "%H:%M:%S %d-%m-%y")

t2 = datetime.datetime.strptime(EndTime, "%H:%M:%S %d-%m-%y")

return str(t2-t1)

Então para:

StartTime = '15:28:53 21-07-13'
EndTime = '15:32:40 21-07-13'

retorna:

'0:03:47'
Aviad
fonte
-10

Obrigado a todos por sua ajuda. Peguei muitas de suas idéias e as reuni, deixe-me saber o que você pensa.

Adicionei dois métodos à classe como este:

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

No meu django eu usei isso (sum é o objeto e está em um dicionário):

<td>{{ sum.0 }}</td>    
<td>{{ sum.1.hours|stringformat:"d" }}:{{ sum.1.minutes|stringformat:"#02.0d" }}</td>
mawcs
fonte
É um pouco longo. Eu sugeriria: def hhmm (self): return ':'. Join (str (td) .split (':') [: 2]) <td> {{sum.1.hhmm}} </td>
joeforker 12/02/09
1
Apenas use divmod () como mostrado no exemplo "Diferença de duas datas" em docs.python.org/release/2.5.2/lib/datetime-timedelta.html
Tom