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'

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+

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


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

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


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.


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']

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']

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

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

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


-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


2
ei, a questão pedir um formato em h: min: seg, não é um simples divisão ..
StupidWolf
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.