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.