Esta es la mejor manera, en mi humilde opinión, ya que puede utilizar la aritmética en el timedelta y cualquier objeto de fecha y hora.
Matthew Schinckel el
13
Esto funciona durante varios días: str(datetime.timedelta(seconds=60*60*24+1))='1 day, 0:00:01'
hyprnick
3
str(datetime.timedelta(seconds=round(666666.55)))representa correctamente los días; suprime los segundos decimales.
CPBL
1
timedeltano es seguro para el desbordamiento y no puede realizar correctamente operaciones matemáticas, por ejemplo, str(timedelta(hours=8) - timedelta(hours=10))el resultado es '-1 day, 22:00:00'y la solución basada en enteros es exactamente para aquellas situaciones en las que necesita '-02:00:00'.
cprn
1
+1. Esta respuesta se puede modificar muy fácilmente. Por ejemplo, si desea omitir un campo al imprimir, use esto: stackoverflow.com/questions/7999935/…
eric_kernfeld
616
Al usar la divmod()función, que solo hace una división para producir tanto el cociente como el resto, puede obtener el resultado muy rápidamente con solo dos operaciones matemáticas:
m, s = divmod(seconds,60)
h, m = divmod(m,60)
Y luego use el formato de cadena para convertir el resultado en la salida deseada:
print('{:d}:{:02d}:{:02d}'.format(h, m, s))# Python 3print(f'{h:d}:{m:02d}:{s:02d}')# Python 3.6+
Si prefiere operadores sobre las funciones, use el módulo; por ejemplo (solo minutos / segundos):'%d:%02dmn' % (seconds / 60, seconds % 60)
bufh
18
Y se puede extender a día: d, h = divmod(h, 24).
Mark Ransom
14
@MarkRansom: y luego a meses m, d = divmod(m, 31). Oooops, no, no puedes. Peor aún, su código será incorrecto si entran segundos en el juego. Larga historia corta: usa timedeltay no te metas con el calendario, te morderá.
44
¿@Tibo se timedeltaocupa de los segundos bisiestos? Sospecho que no. Hay muchas aplicaciones donde esta simple matemática es más que suficiente.
Mark Ransom
1
@MarkRansom str(timedelta(hours=8) - timedelta(hours=10))el resultado es '-1 día, 22:00:00' así que ... idk si funciona con segundos intercalares pero no funciona con números negativos.
cprn
70
Apenas puedo nombrarlo de una manera fácil (al menos no recuerdo la sintaxis), pero es posible usar time.strftime , que brinda más control sobre el formateo:
from time import strftime
from time import gmtime
strftime("%H:%M:%S", gmtime(666))'00:11:06'
strftime("%H:%M:%S", gmtime(60*60*24))'00:00:00'
gmtime se usa para convertir segundos a un formato de tupla especial que strftime()requiere.
Desafortunadamente, este método comienza a medir días a partir de 1, por lo que no está diseñado para representar el delta de tiempo, por lo que es un accidente que espera suceder. Por ejemplo con time.strftime('%d %H:%M:%S', time.gmtime(1))=> '1 día, 0:00:01'.
from time import gmtime
from time import strftime
# NOTE: The following resets if it goes over 23:59:59!
strftime("%H:%M:%S", gmtime(125))# Result: '00:02:05'
strftime("%H:%M:%S", gmtime(60*60*24-1))# Result: '23:59:59'
strftime("%H:%M:%S", gmtime(60*60*24))# Result: '00:00:00'
strftime("%H:%M:%S", gmtime(666777))# Result: '17:12:57'# Wrong
falla si el delta es menos de un segundo:"{:0>8}".format(timedelta(milliseconds=66)) '0:00:00.066000'
jfs
1
Para todos los demás: en el without ':0>8':ejemplo faltan los primeros 0 {:0>8}ceros a la izquierda 8 ceros.
TankorSmash
2
En python 3.5.2, obtengo un TypeError. Estoy formateando una time.time()-startvariable. Alguna idea? TypeError: non-empty format string passed to object.__format__
medley56
Intenté usar en datetime.now()lugar de time.time()generar mi objeto timedelta y obtengo el mismo error.
medley56
@ medley56 Al utilizar python3, es necesario el uso str()si se va usar un formato como 0>8: "{:0>8}".format(str(datetime.timedelta(seconds=666777))). Mira esta respuesta para más información.
Berriel
22
Este es mi truco rápido:
from humanfriendly import format_timespan
secondsPassed =1302
format_timespan(secondsPassed)# '21 minutes and 42 seconds'
En lugar de 1usted, puede usar cualquier número mayor que 0. Aquí usamos el hecho de que datetime.fromordinalsiempre devolverá el datetimeobjeto con un timecomponente cero.
def sec2time(sec, n_msec=3):''' Convert seconds to 'D days, HH:MM:SS.FFF' '''if hasattr(sec,'__len__'):return[sec2time(s)for s in sec]
m, s = divmod(sec,60)
h, m = divmod(m,60)
d, h = divmod(h,24)if n_msec >0:
pattern ='%%02d:%%02d:%%0%d.%df'%(n_msec+3, n_msec)else:
pattern = r'%02d:%02d:%02d'if d ==0:return pattern %(h, m, s)return('%d days, '+ pattern)%(d, h, m, s)
dateutil.relativedeltaes conveniente si necesita acceder a horas, minutos y segundos como flotadores también. datetime.timedeltaNo proporciona una interfaz similar.
from dateutil.relativedelta import relativedelta
rt = relativedelta(seconds=5440)print(rt.seconds)print('{:02d}:{:02d}:{:02d}'.format(
int(rt.hours), int(rt.minutes), int(rt.seconds)))
Estoy obteniendo un resultado diferente al tuyo, lo que me hace pensar que tienes un error tipográfico. Probablemente quisiste usar en seconds=5440lugar de seconds=5540. ¡Sin embargo, me gusta tu respuesta!
JL
2
horas (h) calculadas por división de piso (por //) de segundos por 3600 (60 min / hr * 60 sec / min)
minutos (m) calculados por la división del piso de los segundos restantes (resto del cálculo de la hora, en%) por 60 (60 segundos / min)
de manera similar, segundos (s) por resto de cálculo de hora y minutos.
¡El resto es solo formateo de cadenas!
def hms(seconds):
h = seconds //3600
m = seconds %3600//60
s = seconds %3600%60return'{:02d}:{:02d}:{:02d}'.format(h, m, s)print(hms(7500))# Should print 02h05m00s
Si bien este código puede proporcionar una solución a la pregunta del OP, es mejor agregar contexto sobre por qué / cómo funciona. Esto puede ayudar a los futuros usuarios a aprender y aplicar ese conocimiento a su propio código. También es probable que reciba comentarios positivos de los usuarios en forma de votos positivos, cuando se explique el código.
borchvm
2
¡Lo acabo de hacer, gracias @borchvm por señalar!
Sam
-2
Puedes dividir segundos entre 60 para obtener los minutos
import time
seconds = time.time()
minutes = seconds /60print(minutes)
Cuando lo dividas por 60 nuevamente, obtendrás las horas
Respuestas:
Puedes usar la
datetime.timedelta
función:fuente
str(datetime.timedelta(seconds=60*60*24+1))
='1 day, 0:00:01'
str(datetime.timedelta(seconds=round(666666.55)))
representa correctamente los días; suprime los segundos decimales.timedelta
no es seguro para el desbordamiento y no puede realizar correctamente operaciones matemáticas, por ejemplo,str(timedelta(hours=8) - timedelta(hours=10))
el resultado es'-1 day, 22:00:00'
y la solución basada en enteros es exactamente para aquellas situaciones en las que necesita'-02:00:00'
.Al usar la
divmod()
función, que solo hace una división para producir tanto el cociente como el resto, puede obtener el resultado muy rápidamente con solo dos operaciones matemáticas:Y luego use el formato de cadena para convertir el resultado en la salida deseada:
fuente
'%d:%02dmn' % (seconds / 60, seconds % 60)
d, h = divmod(h, 24)
.m, d = divmod(m, 31)
. Oooops, no, no puedes. Peor aún, su código será incorrecto si entran segundos en el juego. Larga historia corta: usatimedelta
y no te metas con el calendario, te morderá.timedelta
ocupa de los segundos bisiestos? Sospecho que no. Hay muchas aplicaciones donde esta simple matemática es más que suficiente.str(timedelta(hours=8) - timedelta(hours=10))
el resultado es '-1 día, 22:00:00' así que ... idk si funciona con segundos intercalares pero no funciona con números negativos.Apenas puedo nombrarlo de una manera fácil (al menos no recuerdo la sintaxis), pero es posible usar time.strftime , que brinda más control sobre el formateo:
gmtime se usa para convertir segundos a un formato de tupla especial que
strftime()
requiere.fuente
time.strftime('%d %H:%M:%S', time.gmtime(1))
=> '1 día, 0:00:01'.Utilizando
datetime
:Con el
':0>8'
formato:Sin el
':0>8'
formato:Utilizando
time
:fuente
"{:0>8}".format(timedelta(milliseconds=66)) '0:00:00.066000'
without ':0>8':
ejemplo faltan los primeros 0{:0>8}
ceros a la izquierda 8 ceros.time.time()-start
variable. Alguna idea?TypeError: non-empty format string passed to object.__format__
datetime.now()
lugar detime.time()
generar mi objeto timedelta y obtengo el mismo error.str()
si se va usar un formato como0>8
:"{:0>8}".format(str(datetime.timedelta(seconds=666777)))
. Mira esta respuesta para más información.Este es mi truco rápido:
Para obtener más información, visite: https://humanfriendly.readthedocs.io/en/latest/#humanfriendly.format_timespan
fuente
Si necesita obtener
datetime.time
valor, puede usar este truco:No puede agregar
timedelta
atime
, pero puede agregarlo adatetime
.UPD : Otra variación más de la misma técnica:
En lugar de
1
usted, puede usar cualquier número mayor que 0. Aquí usamos el hecho de quedatetime.fromordinal
siempre devolverá eldatetime
objeto con untime
componente cero.fuente
Así es como lo conseguí.
Algunos ejemplos:
fuente
str(datetime.timedelta(seconds=666))
666.0
y666.1
valores.El siguiente set funcionó para mí.
fuente
dateutil.relativedelta
es conveniente si necesita acceder a horas, minutos y segundos como flotadores también.datetime.timedelta
No proporciona una interfaz similar.Huellas dactilares
fuente
seconds=5440
lugar deseconds=5540
. ¡Sin embargo, me gusta tu respuesta!horas (h) calculadas por división de piso (por //) de segundos por 3600 (60 min / hr * 60 sec / min)
minutos (m) calculados por la división del piso de los segundos restantes (resto del cálculo de la hora, en%) por 60 (60 segundos / min)
de manera similar, segundos (s) por resto de cálculo de hora y minutos.
¡El resto es solo formateo de cadenas!
fuente
Puedes dividir segundos entre 60 para obtener los minutos
Cuando lo dividas por 60 nuevamente, obtendrás las horas
fuente
PD: mi código no es profesional
fuente