Formato timedelta a cadena

275

Tengo problemas para formatear un datetime.timedeltaobjeto.

Esto es lo que intento hacer: tengo una lista de objetos y uno de los miembros de la clase del objeto es un objeto timedelta que muestra la duración de un evento. Me gustaría mostrar esa duración en el formato de horas: minutos.

He intentado una variedad de métodos para hacer esto y estoy teniendo dificultades. Mi enfoque actual es agregar métodos a la clase para mis objetos que devuelven horas y minutos. Puedo obtener las horas dividiendo timedelta.seconds entre 3600 y redondeándolo. Tengo problemas para obtener los segundos restantes y convertirlos en minutos.

Por cierto, estoy usando Google AppEngine con plantillas de Django para la presentación.

mawcs
fuente
44
Sería bueno si timedelta tuviera un equivalente del método strftime ().
JS.
@JS. Bueno, de alguna manera puedes si lo usas datetime.utcfromtimestamp(). Vea mi respuesta a continuación.
sjngm
@JS. - 100% de acuerdo. Entonces, __str__of timedeltaes bastante decente, en oposición a __repr__(es decir, ¡para humanos!). Por ejemplo: datetime.timedelta(minutes=6, seconds=41) * 2618 / 48da datetime.timedelta(seconds=21871, microseconds=208333), pero str(datetime.timedelta(minutes=6, seconds=41) * 2618 / 48)da '6:04:31.208333'cuál está bastante bien para leer.
Tomasz Gandor

Respuestas:

213

Simplemente puede convertir el timedelta en una cadena con str (). Aquí hay un ejemplo:

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
Desfile
fuente
13
Más como llamar al método str () con timedelta como argumento.
joeforker
12
No necesita la llamada str allí, se realizará automáticamente mediante impresión.
Zitrax
55
@Zitrax, pero es necesario si va a concatenar el delta con otra cadena. Por ejemploprint 'some thing ' + str(delta)
Plinio.Santos
13
Y es necesario cuando el tipo de datos se define como 'datetime.timedelta' y lo está usando así, ConvertDuration=datetime.timedelta(milliseconds=int(254459))entonces solo usa split para sacar los microsegundos de juego. De 0: 03: 43.765000 puedo obtener 0:03:43 simplemente ejecutandoTotalDuration=str(ConvertDuration).split('.', 2)[0]
DarkXDroid
16
Esto podría imprimir el delta como una cadena, pero no lo formatea como lo solicitó el OP.
Dannid
187

Como sabe, puede obtener los segundos totales de un objeto timedelta accediendo al .secondsatributo.

Python proporciona la función integrada 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

o puede convertir a horas y resto usando una combinación de módulo y resta:

# 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
fuente
55
Para timedeltas negativos, primero debe evaluar el signo y luego hacerlo abs(s).
mbarkhau
27
Tenga en cuenta que es posible que desee utilizar '%d:%02d:%02d'para tener ceros a la izquierda en la cadena de salida.
ShinNoNoir
12
para python 2.7 y superior use el método .total_seconds ()
sk8asd123
27
No utilice .secondssi la diferencia puede ser negativa o superior a 24 horas (el .secondsatributo ignora .days). Use .total_seconds()o su análogo en su lugar.
jfs
Para las diferencias positivas, vuelvo a implementar esto de vez en cuando. Gracias por solo tener que buscar esta vez :)
Wolf
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

Al pasar el timedeltaobjeto a la str()función, se llama al mismo código de formato utilizado si simplemente escribimos print td. Como no desea los segundos, podemos dividir la cadena por dos puntos (3 partes) y volver a unirla con solo las 2 primeras partes.

joeforker
fuente
Gracias por tu respuesta joeforker, pero no estoy seguro de entender tu respuesta. Estoy obteniendo un delta de tiempo a través de datetime - datetime. No se las horas. Además, parece que tu ejemplo incluye segundos, ¿cómo eliminaría eso?
mawcs
1
No importa de dónde obtenga el objeto timedelta, tendrá el mismo formato.
joeforker
9
Si dura más de un día, se formateará como, por ejemplo, "4 días, 8:00" después del procesamiento de división / unión.
joeforker
44
str(my_timedelta)funciona mal para números negativos
Catskul
2
Muestra días también cuando> 24 horas, por ejemplo, '4 días, 18: 48: 22.330000'. Muchos métodos aconsejados aquí no.
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
fuente
3
Muy agradable, sugeriría cambiar if seconds > period_seconds:a if seconds >= period_seconds:sin embargo.
CBenni
1
Esto devuelve cadenas vacías para timedeltas negativos, ¿no está seguro de si esto está destinado?
Dirk
31

Yo personalmente uso la humanizebiblioteca para esto:

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

Por supuesto, no le da exactamente la respuesta que estaba buscando (que es, de hecho, str(timeA - timeB)pero he descubierto que una vez que pasa más de unas horas, la pantalla se vuelve rápidamente ilegible. humanizeTiene soporte para valores mucho más grandes que son legible por humanos, y también está bien localizado.

Al contrib.humanizeparecer, está inspirado en el módulo de Django , por lo que, dado que está utilizando Django, probablemente debería usarlo.

anarcat
fuente
2
Agradable, + 1 aunque: humanize.naturaldelta (pd.Timedelta ('- 10sec')) -> '10 segundos ': S ...
ntg
2
bueno, es un delta de 10 segundos . :) si quieres el tiempo , naturaltimees lo que quieres usar.
anarcat
28

Él ya tiene un objeto timedelta, entonces, ¿por qué no usar su método incorporado total_seconds () para convertirlo en segundos, luego usar divmod () para obtener horas y 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)

Esto funciona independientemente de si el tiempo delta tiene incluso días o años.

Bill Kidd
fuente
23

Aquí hay una función de propósito general para convertir un timedeltaobjeto o un número regular (en forma de segundos o minutos, etc.) en una cadena bien formateada. Tomé respuesta fantástica de mpounsett sobre una cuestión duplicado, hecho que sea un poco más flexible, legibilidad mejorada y documentación añadida.

Encontrará que es la respuesta más flexible aquí hasta ahora, ya que le permite:

  1. Personalice el formato de cadena sobre la marcha en lugar de que esté codificado.
  2. Deje ciertos intervalos de tiempo sin problemas (vea los ejemplos a continuación).

Función:

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)

Manifestación:

>>> 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
Queso Marred
fuente
Muy bonito, código limpio! Me pregunto cómo se puede expandir este código para manejar los últimos segundos fraccionarios restantes en el formateador ...
kfmfe04
17

Sé que esta es una vieja pregunta respondida, pero la uso datetime.utcfromtimestamp()para esto. Tarda el número de segundos y devuelve un datetimeque puede formatearse como cualquier otro datetime.

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

Mientras permanezca en los rangos legales durante las partes de tiempo, esto debería funcionar, es decir, no devuelve 1234: 35 ya que las horas son <= 23.

sjngm
fuente
2
deberías usar print timedelta(seconds=end - begin)en su lugar.
jfs
@JFSebastian Entonces tendrías que rellenar las horas manualmente con ceros a la izquierda.
sjngm
No veo nada sobre el relleno en la pregunta. Úselo .zfill(8)si lo necesita.
jfs
1
Necesita una llamada .total_seconds (): >>> datetime.utcfromtimestamp ((t2-t1) .total_seconds ()). Strftime ("% H:% M:% S") <<< >>> '00: 00: 05 '
cagney
2
Prefiero esta solución, le permite controlar el formato. Tenga en cuenta que también puede usar el formateador de str directamente así: "{0:% H}: {0:% M}". Format (duración)
dedos de los pies del
15

El interlocutor quiere un formato más agradable que el 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'

Entonces, realmente hay dos formatos, uno donde los días son 0 y se omite, y otro donde hay texto "n días, h: m: s". Pero, los segundos pueden tener fracciones, y no hay ceros a la izquierda en las impresiones, por lo que las columnas son desordenadas.

Aquí está mi rutina, si te gusta:

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

esto devuelve la salida como dd: hh: mm: ss formato:

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

Pensé en agregar años a esto, pero esto se deja como un ejercicio para el lector, ya que la salida es segura en más de 1 año:

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

Consideraría seriamente el enfoque de la Navaja de Occam aquí:

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

Esto devuelve una cadena sin los microsegundos

Si desea regenerar el objeto datetime.timedelta, simplemente haga esto:

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

¡2 años después, me encanta este idioma!

Piroterma
fuente
55
Esto no cubre días
Waschbaer
13

Mis datetime.timedeltaobjetos fueron más de un día. Así que aquí hay otro problema. Toda la discusión anterior supone menos de un día. A timedeltaes en realidad una tupla de días, segundos y microsegundos. La discusión anterior debe usarse td.secondscomo lo hizo Joe, pero si tiene días NO se incluye en el valor de segundos.

Estoy obteniendo un lapso de tiempo entre 2 fechas y días de impresión y horas.

span = currentdt - previousdt
print '%d,%d\n' % (span.days,span.seconds/3600)
Alex L
fuente
Esta es la solución a prueba de futuro.
Jibin
11

Utilicé la humanfriendlybiblioteca de Python para hacer esto, funciona muy bien.

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

'5 minutes and 21 seconds'

Disponible en https://pypi.org/project/humanfriendly/

Dhiraj Gupta
fuente
7

Siguiendo el valor de ejemplo de Joe anterior, usaría el operador aritmético de módulo, por lo tanto:

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

Tenga en cuenta que la división de enteros en Python se redondea por defecto; si desea ser más explícito, use math.floor () o math.ceil () según corresponda.

UltraNurd
fuente
timedelta ya sabe cómo formatearse, como en 'print some_timedelta'.
joeforker
Sí, pero no puede aceptar una cadena de formato arbitrario, que es lo que Michael estaba preguntando. Aunque ahora que lo pienso, 3600 division mod hace la suposición de horas-segundos que causa problemas en los segundos bisiestos.
UltraNurd
Sí, pero no quiere una cadena de formato arbitrario, quiere casi exactamente el comportamiento predeterminado.
joeforker
2
No olvides // para truncar la división en Python 3000
joeforker
3
+1, pero ¿por qué no editas la respuesta para usar //? También sugiero usar en td.total_seconds()lugar de .secondshacerlo funcionar por intervalos> 1 día.
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
fuente
¿Escribiste este? ¿Cuánto lo probaste?
Thomas Ahle
Estoy usando este código en mi proyecto llamado datahaven.net . Funciona bastante bien ¿Viste algún error?
Veselin Penev
Siempre es bueno si puede proporcionar un poco de información con una respuesta tan fuerte de código :) Como un ejemplo de cómo funciona, posibles fortalezas y debilidades.
Thomas Ahle
1
Oh. ¡Por supuesto!. Se agregó un ejemplo para ti. :-)
Veselin Penev
Super :) También timedeltatenga en cuenta que el objeto tiene los campos days, secondsy microsecondspor la documentación.
Thomas Ahle
4

Tuve un problema similar con la salida del cálculo de horas extra en el trabajo. El valor siempre debe aparecer en HH: MM, incluso cuando es mayor de un día y el valor puede ser negativo. Combiné algunas de las soluciones mostradas y tal vez alguien más encuentre útil esta solución. Me di cuenta de que si el valor de timedelta es negativo, la mayoría de las soluciones que se muestran con el método divmod no funcionan de inmediato:

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 a HH: MM cadena:

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
fuente
4
import datetime
hours = datetime.timedelta(hours=16, minutes=30)
print((datetime.datetime(1,1,1) + hours).strftime('%H:%M'))
SleX
fuente
2
en 3.7 obtengo AttributeError: el objeto 'datetime.timedelta' no tiene atributo 'strftime'
qubodup
4

Un filtro de plantilla directo para este problema. La función integrada int () nunca se redondea. Las cadenas F (es decir, f '') requieren 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
Patricio
fuente
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)

Esto producirá:

>>> from datetime import timedelta
>>> localize_timedelta(timedelta(days=3660, minutes=500))
'10 years 10 days 8 hours 20 minutes'
Artem Vasilev
fuente
La más neta en mi opinión, en términos de longitud y de lo que cubre
Dici
1

Verifique esta función: convierte el objeto timedelta en la cadena '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
fuente
1

Un trazador de líneas. Dado que timedeltas no ofrecen el tiempo de espera de datetime, devuelva el timedelta a datetime y use stftime.

Esto no solo puede lograr el formato solicitado por el OP Horas: minutos, ahora puede aprovechar todo el poder de formateo del tiempo de espera de datetime, si sus requisitos cambian a otra representación.

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

Esto también resuelve la molestia de que las timedeltas estén formateadas en cadenas como H: MM: SS en lugar de HH: MM: SS, lo que me lleva a este problema y a la solución que he compartido.

Bill Gale
fuente
0

Si ya tiene un obj timedelta, simplemente convierta ese obj en una cadena. Elimine los últimos 3 caracteres de la cadena e imprima. Esto truncará la parte de segundos e imprimirá el resto en el formato Horas: Minutos.

t = str(timedeltaobj) 

print t[:-3]
Sima
fuente
El -3 no funciona, mejor usoprint t.split('.')[0]
EvgenyKolyakov
0

Si tiene IPythonen sus paquetes (debería), tiene (hasta ahora, de todos modos) un formateador muy agradable para duraciones (en segundos flotantes). Eso se usa en varios lugares, por ejemplo, por la %%timemagia celular. Me gusta el formato que produce para duraciones cortas:

>>> 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
fuente
-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)

Entonces para:

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

devoluciones:

'0:03:47'
Aviad
fuente
-10

Gracias a todos por su ayuda. Tomé muchas de tus ideas y las puse juntas, déjame saber lo que piensas.

Agregué dos métodos a la clase 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

En mi django usé esto (sum es el objeto y está en un diccionario):

<td>{{ sum.0 }}</td>    
<td>{{ sum.1.hours|stringformat:"d" }}:{{ sum.1.minutes|stringformat:"#02.0d" }}</td>
mawcs
fuente
Es un poco largo Sugeriría: def hhmm (self): return ':'. Join (str (td) .split (':') [: 2]) <td> {{sum.1.hhmm}} </td>
joeforker
1
Solo use divmod () como se muestra en el ejemplo de "Diferencia de dos fechas" en docs.python.org/release/2.5.2/lib/datetime-timedelta.html
Tom