¿Cómo convierto segundos a horas, minutos y segundos?


Respuestas:


764

Puedes usar la datetime.timedeltafunción:

>>> import datetime
>>> str(datetime.timedelta(seconds=666))
'0:11:06'

99
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 3
print(f'{h:d}:{m:02d}:{s:02d}') # Python 3.6+

2
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.

Nota: Trunca después de las 23:59:59


Bueno, la respuesta se proporciona aquí: stackoverflow.com/questions/1384406/…
anatoly techtonik

13
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'.
Riaz Rizvi

41

Utilizando datetime:

Con el ':0>8'formato:

from datetime import timedelta

"{:0>8}".format(str(timedelta(seconds=66)))
# Result: '00:01:06'

"{:0>8}".format(str(timedelta(seconds=666777)))
# Result: '7 days, 17:12:57'

"{:0>8}".format(str(timedelta(seconds=60*60*49+109)))
# Result: '2 days, 1:01:49'

Sin el ':0>8'formato:

"{}".format(str(timedelta(seconds=66)))
# Result: '00:01:06'

"{}".format(str(timedelta(seconds=666777)))
# Result: '7 days, 17:12:57'

"{}".format(str(timedelta(seconds=60*60*49+109)))
# Result: '2 days, 1:01:49'

Utilizando time:

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

1
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


9

Si necesita obtener datetime.timevalor, puede usar este truco:

my_time = (datetime(1970,1,1) + timedelta(seconds=my_seconds)).time()

No puede agregar timedeltaa time, pero puede agregarlo a datetime.

UPD : Otra variación más de la misma técnica:

my_time = (datetime.fromordinal(1) + timedelta(seconds=my_seconds)).time()

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.


6

Así es como lo conseguí.

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)

Algunos ejemplos:

$ sec2time(10, 3)
Out: '00:00:10.000'

$ sec2time(1234567.8910, 0)
Out: '14 days, 06:56:07'

$ sec2time(1234567.8910, 4)
Out: '14 days, 06:56:07.8910'

$ sec2time([12, 345678.9], 3)
Out: ['00:00:12.000', '4 days, 00:01:18.900']

1
¿Cuál es la ventaja de esto sobre la respuesta anterior? str(datetime.timedelta(seconds=666))
Riaz Rizvi

@RiazRizvi proporciona una longitud de cadena consistente para microsegundos para 666.0y 666.1valores.
anatoly techtonik

6

El siguiente set funcionó para mí.

def sec_to_hours(seconds):
    a=str(seconds//3600)
    b=str((seconds%3600)//60)
    c=str((seconds%3600)%60)
    d=["{} hours {} mins {} seconds".format(a, b, c)]
    return d


print(sec_to_hours(10000))
# ['2 hours 46 mins 40 seconds']

print(sec_to_hours(60*60*24+105))
# ['24 hours 1 mins 45 seconds']

3

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

Huellas dactilares

40.0
01:30:40

1
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 % 60
    return '{: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 / 60
print(minutes)

Cuando lo dividas por 60 nuevamente, obtendrás las horas


-3

division = 3623 // 3600 #to hours
division2 = 600 // 60 #to minutes
print (division) #write hours
print (division2) #write minutes

PD: mi código no es profesional


2
oye, la pregunta pide un formato en horas: min: seg, no es una división simple ..
StupidWolf
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.