Como converter segundos em horas, minutos e segundos?

Respostas:

764

Você pode usar a datetime.timedeltafunção:

>>> import datetime
>>> str(datetime.timedelta(seconds=666))
'0:11:06'
SilentGhost
fonte
9
Esta é a melhor maneira, IMHO, pois você pode usar aritmética na timedelta e em qualquer objeto de data e hora.
Matthew Schinckel
13
Isso funciona por vários dias: str(datetime.timedelta(seconds=60*60*24+1))='1 day, 0:00:01'
hyprnick
3
str(datetime.timedelta(seconds=round(666666.55)))processa corretamente dias; suprime os segundos decimais.
CPBL 27/11
1
timedeltanão é seguro contra transbordamento e não pode executar operações matemáticas corretamente, por exemplo, str(timedelta(hours=8) - timedelta(hours=10))o resultado é '-1 day, 22:00:00'e a solução baseada em números inteiros é exatamente para as situações em que você precisa '-02:00:00'.
CPRN
1
+1. Esta resposta pode ser modificada com muita facilidade. Por exemplo, se você quiser omitir um campo ao imprimir, use o seguinte: stackoverflow.com/questions/7999935/…
eric_kernfeld 10/10
616

Usando a divmod()função, que faz apenas uma única divisão para produzir o quociente e o restante, é possível obter o resultado muito rapidamente com apenas duas operações matemáticas:

m, s = divmod(seconds, 60)
h, m = divmod(m, 60)

E, em seguida, use a formatação de string para converter o resultado na saída desejada:

print('{:d}:{:02d}:{:02d}'.format(h, m, s)) # Python 3
print(f'{h:d}:{m:02d}:{s:02d}') # Python 3.6+
Brandon Rhodes
fonte
2
Se você preferir operadores sobre funções, use o módulo; por exemplo (apenas minutos / segundos):'%d:%02dmn' % (seconds / 60, seconds % 60)
bufh 20/05
18
E você pode estendê-lo para dias: d, h = divmod(h, 24).
Mark Ransom
14
@ MarkRansom: e depois para meses m, d = divmod(m, 31). Oooops, não, você não pode. Pior, seu código estará errado se segundos de pulo entrarem no jogo. Para encurtar a história: use timedeltae não mexa no calendário, ele vai te morder.
4
@Tibo timedeltalida com segundos bissextos? Eu suspeito que não. Existem muitas aplicações em que essa matemática simples é mais que suficiente.
Mark Ransom
1
@MarkRansom str(timedelta(hours=8) - timedelta(hours=10))o resultado é '-1 dia, 22:00:00', então ... idk se funcionar com segundos bissextos, mas não funcionar com números negativos.
Cprn
70

Eu dificilmente posso nomear isso de uma maneira fácil (pelo menos não me lembro da sintaxe), mas é possível usar time.strftime , que oferece mais controle sobre a formatação:

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'

O gmtime é usado para converter segundos em um formato especial de tupla que strftime()requer.

Nota: Trunca após 23:59:59

anatoly techtonik
fonte
Bem, a resposta é realmente fornecida aqui - stackoverflow.com/questions/1384406/…
anatoly techtonik
13
Infelizmente, esse método começa a medir dias a partir de 1, para que não seja projetado para representar um delta de tempo e, portanto, é um acidente esperando para acontecer. Por exemplo, com time.strftime('%d %H:%M:%S', time.gmtime(1))=> '1 dia, 0:00:01'.
Riaz Rizvi
41

Usando datetime:

Com o ':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'

Sem o ':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'

Usando 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
fonte
1
falhará se o delta for menor que um segundo:"{:0>8}".format(timedelta(milliseconds=66)) '0:00:00.066000'
jfs
1
Para todos os outros: O without ':0>8':exemplo está faltando um {:0>8}zero inicial à esquerda e 8 zeros à esquerda.
TankorSmash 24/07
2
No python 3.5.2, recebo um TypeError. Estou formatando uma time.time()-startvariável. Alguma visão? TypeError: non-empty format string passed to object.__format__
precisa saber é o seguinte
Tentei usar em datetime.now()vez de time.time()gerar meu objeto timedelta e recebo o mesmo erro.
medley56
@ medley56 Ao usar Python3, você precisa usar str()se você estiver indo usar um formato como 0>8: "{:0>8}".format(str(datetime.timedelta(seconds=666777))). Verifique esta resposta para mais informações.
Berriel
22

Este é o meu truque rápido:

from humanfriendly import format_timespan
secondsPassed = 1302
format_timespan(secondsPassed)
# '21 minutes and 42 seconds'

Para mais informações, visite: https://humanfriendly.readthedocs.io/en/latest/#humanfriendly.format_timespan

doories
fonte
Você não tem ideia de quanto tempo eu estava procurando por essa resposta. Muito obrigado. Eu gostaria de poder dar a você mais de um +1.
Peppa
9

Se você precisar obter datetime.timevalor, poderá usar este truque:

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

Você não pode adicionar timedeltaa time, mas pode adicioná-lo a datetime.

UPD : Ainda outra variação da mesma técnica:

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

Em vez de 1você pode usar qualquer número maior que 0. Aqui usamos o fato de que datetime.fromordinalsempre retornará datetimeobjeto com o timecomponente sendo zero.

MarSoft
fonte
6

É assim que eu entendi.

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)

Alguns exemplos:

$ 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']
Lee
fonte
1
Qual é a vantagem disso sobre a resposta acima? str(datetime.timedelta(seconds=666))
Riaz Rizvi 01/01
O @RiazRizvi fornece um comprimento consistente de seqüência de caracteres para microssegundos 666.0e 666.1valores.
techtonik anatoly
6

O seguinte conjunto funcionou para mim.

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 ingênuo
fonte
3

dateutil.relativedeltaé conveniente se você também precisar acessar horas, minutos e segundos enquanto flutua. datetime.timedeltanão fornece uma interface semelhante.

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

Impressões

40.0
01:30:40
teekarna
fonte
1
Estou tendo uma saída diferente da sua, o que me faz pensar que você tem um erro de digitação. Você provavelmente quis usar em seconds=5440vez de seconds=5540. Eu gosto da sua resposta!
JL
2

horas (h) calculadas pela divisão do piso (por //) de segundos em 3600 (60 min / h * 60 seg / min)

minutos (m) calculados pela divisão do piso dos segundos restantes (restante do cálculo da hora, em%) por 60 (60 s / min)

da mesma forma, segundos (s) pelo restante do cálculo de horas e minutos.

O resto é apenas formatação de string!

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
fonte
Embora esse código possa fornecer uma solução para a pergunta do OP, é melhor adicionar contexto sobre o porquê / como ele funciona. Isso pode ajudar os usuários futuros a aprender e aplicar esse conhecimento ao seu próprio código. Também é provável que você tenha um feedback positivo dos usuários na forma de upvotes, quando o código for explicado.
borchvm 10/02
2
Acabei de fazer, Obrigado @borchvm por apontar!
Sam
-2

Você pode dividir segundos por 60 para obter os minutos

import time
seconds = time.time()
minutes = seconds / 60
print(minutes)

Ao dividi-lo por 60 novamente, você receberá as horas

alosha002
fonte
-3

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

PS Meu código não é profissional

Denis Kerstens Denisik35
fonte
2
ei, a questão pedir um formato em h: min: seg, não é um simples divisão ..
StupidWolf