Tengo problemas para formatear un datetime.timedelta
objeto.
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.
datetime.utcfromtimestamp()
. Vea mi respuesta a continuación.__str__
oftimedelta
es bastante decente, en oposición a__repr__
(es decir, ¡para humanos!). Por ejemplo:datetime.timedelta(minutes=6, seconds=41) * 2618 / 48
dadatetime.timedelta(seconds=21871, microseconds=208333)
, perostr(datetime.timedelta(minutes=6, seconds=41) * 2618 / 48)
da'6:04:31.208333'
cuál está bastante bien para leer.Respuestas:
Simplemente puede convertir el timedelta en una cadena con str (). Aquí hay un ejemplo:
fuente
print 'some thing ' + str(delta)
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]
Como sabe, puede obtener los segundos totales de un objeto timedelta accediendo al
.seconds
atributo.Python proporciona la función integrada
divmod()
que permite:o puede convertir a horas y resto usando una combinación de módulo y resta:
fuente
abs(s)
.'%d:%02d:%02d'
para tener ceros a la izquierda en la cadena de salida..seconds
si la diferencia puede ser negativa o superior a 24 horas (el.seconds
atributo ignora.days
). Use.total_seconds()
o su análogo en su lugar.Al pasar el
timedelta
objeto a lastr()
función, se llama al mismo código de formato utilizado si simplemente escribimosprint 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.fuente
str(my_timedelta)
funciona mal para números negativosfuente
if seconds > period_seconds:
aif seconds >= period_seconds:
sin embargo.Yo personalmente uso la
humanize
biblioteca para esto: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.humanize
Tiene soporte para valores mucho más grandes que son legible por humanos, y también está bien localizado.Al
contrib.humanize
parecer, está inspirado en el módulo de Django , por lo que, dado que está utilizando Django, probablemente debería usarlo.fuente
naturaltime
es lo que quieres usar.É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?
Esto funciona independientemente de si el tiempo delta tiene incluso días o años.
fuente
Aquí hay una función de propósito general para convertir un
timedelta
objeto 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:
Función:
Manifestación:
fuente
Sé que esta es una vieja pregunta respondida, pero la uso
datetime.utcfromtimestamp()
para esto. Tarda el número de segundos y devuelve undatetime
que puede formatearse como cualquier otrodatetime
.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.
fuente
print timedelta(seconds=end - begin)
en su lugar..zfill(8)
si lo necesita.El interlocutor quiere un formato más agradable que el típico:
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:
esto devuelve la salida como dd: hh: mm: ss formato:
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:
fuente
Consideraría seriamente el enfoque de la Navaja de Occam aquí:
Esto devuelve una cadena sin los microsegundos
Si desea regenerar el objeto datetime.timedelta, simplemente haga esto:
¡2 años después, me encanta este idioma!
fuente
Mis
datetime.timedelta
objetos fueron más de un día. Así que aquí hay otro problema. Toda la discusión anterior supone menos de un día. Atimedelta
es en realidad una tupla de días, segundos y microsegundos. La discusión anterior debe usarsetd.seconds
como 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.
fuente
Utilicé la
humanfriendly
biblioteca de Python para hacer esto, funciona muy bien.Disponible en https://pypi.org/project/humanfriendly/
fuente
Siguiendo el valor de ejemplo de Joe anterior, usaría el operador aritmético de módulo, por lo tanto:
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.
fuente
td.total_seconds()
lugar de.seconds
hacerlo funcionar por intervalos> 1 día.fuente
timedelta
tenga en cuenta que el objeto tiene los camposdays
,seconds
ymicroseconds
por la documentación.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:
timedelta a HH: MM cadena:
fuente
fuente
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.
fuente
Esto producirá:
fuente
Verifique esta función: convierte el objeto timedelta en la cadena 'HH: MM: SS'
fuente
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.
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.
fuente
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.
fuente
print t.split('.')[0]
Si tiene
IPython
en 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%%time
magia celular. Me gusta el formato que produce para duraciones cortas:fuente
Entonces para:
devoluciones:
fuente
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:
En mi django usé esto (sum es el objeto y está en un diccionario):
fuente