Come faccio a convertire i secondi in ore, minuti e secondi?


Risposte:


764

Puoi usare la datetime.timedeltafunzione:

>>> import datetime
>>> str(datetime.timedelta(seconds=666))
'0:11:06'

9
Questo è il modo migliore, IMHO, poiché puoi quindi usare l'aritmetica su timedelta e su qualsiasi oggetto datetime.
Matthew Schinckel,

13
Funziona per più giorni: str(datetime.timedelta(seconds=60*60*24+1))='1 day, 0:00:01'
hyprnick il

3
str(datetime.timedelta(seconds=round(666666.55)))rende correttamente i giorni; sopprime i secondi decimali.
CPBL,

1
timedeltanon è troppo sicuro e non può eseguire correttamente operazioni matematiche, ad esempio str(timedelta(hours=8) - timedelta(hours=10))il risultato è '-1 day, 22:00:00'e la soluzione basata su numeri interi è esattamente per quelle situazioni in cui è necessario '-02:00:00'.
cprn,

1
+1. Questa risposta può essere modificata molto facilmente. Per esempio, se si desidera omettere un campo durante la stampa, utilizzare questo: stackoverflow.com/questions/7999935/...
eric_kernfeld

616

Usando la divmod()funzione, che fa una sola divisione per produrre sia il quoziente che il resto, puoi ottenere il risultato molto rapidamente con solo due operazioni matematiche:

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

Quindi utilizzare la formattazione di stringa per convertire il risultato nell'output desiderato:

print('{:d}:{:02d}:{:02d}'.format(h, m, s)) # Python 3
print(f'{h:d}:{m:02d}:{s:02d}') # Python 3.6+

2
Se preferisci gli operatori alle funzioni, usa il modulo; ad esempio (solo minuti / secondi):'%d:%02dmn' % (seconds / 60, seconds % 60)
bufh

18
E si può estenderlo a giorni: d, h = divmod(h, 24).
Mark Ransom,

14
@MarkRansom: e poi a mesi m, d = divmod(m, 31). Oooops, no, non puoi. Peggio ancora, il tuo codice sarà sbagliato se entrano in gioco secondi saltati. Per timedeltafarla breve: usa e non scherzare con il calendario, ti morderà.

4
@Tibo si timedeltaoccupa dei secondi bisestili? Sospetto di no. Ci sono molte applicazioni in cui questa semplice matematica è più che sufficiente.
Mark Ransom,

1
@MarkRansom str(timedelta(hours=8) - timedelta(hours=10))il risultato è '-1 giorno, 22:00:00' quindi ... idk se funziona con secondi saltati ma non funziona con numeri negativi.
cprn,

70

Riesco a malapena a nominarlo in modo semplice (almeno non ricordo la sintassi), ma è possibile usare time.strftime , che offre un maggiore controllo sulla formattazione:

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 è usato per convertire i secondi in uno speciale formato di tupla che strftime()richiede.

Nota: tronca dopo le 23:59:59


Bene, la risposta è in realtà fornito qui - stackoverflow.com/questions/1384406/...
techtonik Anatoly

13
Sfortunatamente questo metodo inizia a misurare i giorni da 1 quindi non è progettato per rappresentare il delta temporale, quindi è un incidente in attesa di accadere. Ad esempio con time.strftime('%d %H:%M:%S', time.gmtime(1))=> '1 giorno, 0:00:01'.
Riaz Rizvi,

41

Utilizzando datetime:

Con il ':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'

Senza il ':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'

Utilizzando 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
fallisce se il delta è meno di un secondo:"{:0>8}".format(timedelta(milliseconds=66)) '0:00:00.066000'
jfs

1
A tutti gli altri: without ':0>8':nell'esempio mancano i 0. {:0>8}zero pad iniziali agli 8 zero di sinistra.
TankorSmash,

2
In Python 3.5.2 ottengo un TypeError. Sto formattando una time.time()-startvariabile. Qualche idea? TypeError: non-empty format string passed to object.__format__
medley56,

Ho provato a utilizzare datetime.now()invece di time.time()generare il mio oggetto timedelta e ottengo lo stesso errore.
medley56,

@ medley56 Quando si utilizza python3, è necessario utilizzare str()se si sta andando utilizzare un formato come 0>8: "{:0>8}".format(str(datetime.timedelta(seconds=666777))). Controlla questa risposta per maggiori informazioni.
Berriel,


9

Se hai bisogno di ottenere datetime.timevalore, puoi usare questo trucco:

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

Non puoi aggiungere timedeltaa time, ma puoi aggiungerlo a datetime.

UPD : Ancora un'altra variante della stessa tecnica:

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

Invece di 1te puoi usare qualsiasi numero maggiore di 0. Qui usiamo il fatto che datetime.fromordinalrestituirà sempre l' datetimeoggetto con timecomponente pari a zero.


6

Ecco come l'ho preso.

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)

Qualche esempio:

$ 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 è il vantaggio di questo rispetto alla risposta sopra? str(datetime.timedelta(seconds=666))
Riaz Rizvi,

@RiazRizvi fornisce una lunghezza stringa costante per microsecondi 666.0e 666.1valori.
Anatoly Techtonik,

6

Il seguente set ha funzionato per me.

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è utile se è necessario accedere a ore, minuti e secondi anche come float. datetime.timedeltanon fornisce un'interfaccia simile.

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

stampe

40.0
01:30:40

1
Sto ottenendo un output diverso dal tuo, il che mi fa pensare che tu abbia un refuso. Probabilmente intendevi usare seconds=5440invece di seconds=5540. Mi piace la tua risposta, però!
JL

2

ore (h) calcolate per divisione del pavimento (per //) di secondi per 3600 (60 min / ora * 60 sec / min)

minuti (m) calcolati per divisione del pavimento dei secondi rimanenti (resto dal calcolo dell'ora, per%) per 60 (60 sec / min)

allo stesso modo, i secondi per il resto del calcolo delle ore e dei minuti.

Il resto è solo la formattazione delle stringhe!

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

Sebbene questo codice possa fornire una soluzione alla domanda del PO, è meglio aggiungere un contesto sul perché / come funziona. Questo può aiutare gli utenti futuri a imparare e applicare tali conoscenze al proprio codice. È inoltre probabile che tu riceva un feedback positivo dagli utenti sotto forma di valutazioni, quando viene spiegato il codice.
Borchvm,

2
Ho appena fatto, grazie @borchvm per avermelo fatto notare!
Sam,

-2

Puoi dividere i secondi per 60 per ottenere i minuti

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

Quando lo dividi di nuovo per 60, otterrai le ore


-3

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

PS Il mio codice non è professionale


2
ehi, la domanda richiede un formato in ore: min: sec, non una semplice divisione ..
StupidWolf
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.