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