Eu tenho uma função que retorna informações em segundos, mas preciso armazenar essas informações em horas: minutos: segundos.
Existe uma maneira fácil de converter os segundos para esse formato em Python?
Eu tenho uma função que retorna informações em segundos, mas preciso armazenar essas informações em horas: minutos: segundos.
Existe uma maneira fácil de converter os segundos para esse formato em Python?
Respostas:
Você pode usar a datetime.timedelta
função:
>>> import datetime
>>> str(datetime.timedelta(seconds=666))
'0:11:06'
str(datetime.timedelta(seconds=60*60*24+1))
='1 day, 0:00:01'
str(datetime.timedelta(seconds=round(666666.55)))
processa corretamente dias; suprime os segundos decimais.
timedelta
nã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'
.
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+
'%d:%02dmn' % (seconds / 60, seconds % 60)
d, h = divmod(h, 24)
.
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 timedelta
e não mexa no calendário, ele vai te morder.
timedelta
lida com segundos bissextos? Eu suspeito que não. Existem muitas aplicações em que essa matemática simples é mais que suficiente.
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.
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
time.strftime('%d %H:%M:%S', time.gmtime(1))
=> '1 dia, 0:00:01'.
datetime
:':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'
':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'
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
"{:0>8}".format(timedelta(milliseconds=66)) '0:00:00.066000'
without ':0>8':
exemplo está faltando um {:0>8}
zero inicial à esquerda e 8 zeros à esquerda.
time.time()-start
variável. Alguma visão? TypeError: non-empty format string passed to object.__format__
datetime.now()
vez de time.time()
gerar meu objeto timedelta e recebo o mesmo erro.
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.
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
Se você precisar obter datetime.time
valor, poderá usar este truque:
my_time = (datetime(1970,1,1) + timedelta(seconds=my_seconds)).time()
Você não pode adicionar timedelta
a 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 1
você pode usar qualquer número maior que 0. Aqui usamos o fato de que datetime.fromordinal
sempre retornará datetime
objeto com o time
componente sendo zero.
É 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']
str(datetime.timedelta(seconds=666))
666.0
e 666.1
valores.
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']
dateutil.relativedelta
é conveniente se você também precisar acessar horas, minutos e segundos enquanto flutua. datetime.timedelta
nã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
seconds=5440
vez de seconds=5540
. Eu gosto da sua resposta!
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
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