¿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'
SilentGhost
fuente
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+
Brandon Rhodes
fuente
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

anatoly techtonik
fuente
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
marcell
fuente
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.

MarSoft
fuente
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']
Sotavento
fuente
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']
decodificador ingenuo
fuente
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
teekarna
fuente
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
Sam
fuente
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

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

Denis Kerstens Denisik35
fuente
2
oye, la pregunta pide un formato en horas: min: seg, no es una división simple ..
StupidWolf