Comment convertir des secondes en heures, minutes et secondes?

Réponses:

764

Vous pouvez utiliser la datetime.timedeltafonction:

>>> import datetime
>>> str(datetime.timedelta(seconds=666))
'0:11:06'
SilentGhost
la source
9
C'est la meilleure façon, à mon humble avis, car vous pouvez ensuite utiliser l'arithmétique sur le timedelta et tous les objets datetime.
Matthew Schinckel
13
Cela fonctionne pendant plusieurs jours: str(datetime.timedelta(seconds=60*60*24+1))='1 day, 0:00:01'
hyprnick
3
str(datetime.timedelta(seconds=round(666666.55)))rend correctement les jours; supprime les secondes décimales.
CPBL
1
timedeltan'est pas sûr de débordement et ne peut pas effectuer correctement les opérations mathématiques, par exemple str(timedelta(hours=8) - timedelta(hours=10))le résultat est '-1 day, 22:00:00'et la solution basée sur des nombres entiers est exactement pour les situations où vous en avez besoin '-02:00:00'.
cprn
1
+1. Cette réponse peut être modifiée très facilement. Par exemple, si vous souhaitez omettre un champ lors de l'impression, utilisez ceci: stackoverflow.com/questions/7999935/…
eric_kernfeld
616

En utilisant la divmod()fonction, qui ne fait qu'une seule division pour produire à la fois le quotient et le reste, vous pouvez obtenir le résultat très rapidement avec seulement deux opérations mathématiques:

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

Et puis utilisez le formatage de chaîne pour convertir le résultat en sortie souhaitée:

print('{:d}:{:02d}:{:02d}'.format(h, m, s)) # Python 3
print(f'{h:d}:{m:02d}:{s:02d}') # Python 3.6+
Brandon Rhodes
la source
2
Si vous préférez les opérateurs aux fonctions, utilisez le modulo; par exemple (seulement minutes / secondes):'%d:%02dmn' % (seconds / 60, seconds % 60)
bufh
18
Et vous pouvez l' étendre à jour: d, h = divmod(h, 24).
Mark Ransom
14
@MarkRansom: puis aux mois m, d = divmod(m, 31). Oups, non, vous ne pouvez pas. Pire encore, votre code sera erroné si des secondes intercalaires entrent en jeu. Pour faire court: utilisez timedeltale calendrier et ne le dérangez pas, il vous mordra.
4
@Tibo gère timedeltales secondes intercalaires ? Je suppose que non. Il existe de nombreuses applications où ce calcul simple est plus que suffisant.
Mark Ransom
1
@MarkRansom str(timedelta(hours=8) - timedelta(hours=10))le résultat est '-1 jour, 22:00:00' donc ... idk s'il fonctionne avec des secondes intercalaires mais ne fonctionne pas avec des nombres négatifs.
cprn
70

Je peux difficilement nommer cela d'une manière facile (au moins je ne me souviens pas de la syntaxe), mais il est possible d'utiliser time.strftime , qui donne plus de contrôle sur le formatage:

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 est utilisé pour convertir les secondes en un format de tuple spécial qui le strftime()requiert.

Remarque: tronque après 23:59:59

anatoly techtonik
la source
Eh bien, la réponse est réellement fournie ici - stackoverflow.com/questions/1384406/…
anatoly techtonik
13
Malheureusement, cette méthode commence à mesurer les jours à partir de 1, elle n'est donc pas conçue pour représenter le delta de temps, et c'est donc un accident qui attend. Par exemple avec time.strftime('%d %H:%M:%S', time.gmtime(1))=> '1 jour, 0:00:01'.
Riaz Rizvi
41

En utilisant datetime:

Au ':0>8'format:

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'

Sans le ':0>8'format:

"{}".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'

En utilisant 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
la source
1
il échoue si le delta est inférieur à une seconde:"{:0>8}".format(timedelta(milliseconds=66)) '0:00:00.066000'
jfs
1
Pour tout le monde: dans l' without ':0>8':exemple, il manque un 0. {:0>8}zéro zéro en tête pour les 8 zéros à gauche.
TankorSmash
2
En python 3.5.2, j'obtiens une TypeError. Je formate une time.time()-startvariable. Un aperçu? TypeError: non-empty format string passed to object.__format__
medley56
J'ai essayé d'utiliser datetime.now()au lieu de time.time()pour générer mon objet timedelta et j'obtiens la même erreur.
medley56
@ medley56 Lorsque vous utilisez python3, vous devez utiliser str()si vous allez utiliser un format tel que 0>8: "{:0>8}".format(str(datetime.timedelta(seconds=666777))). Vérifiez cette réponse pour plus d'informations.
Berriel
9

Si vous avez besoin d'obtenir de la datetime.timevaleur, vous pouvez utiliser cette astuce:

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

Vous ne pouvez pas ajouter timedeltaà time, mais pouvez l'ajouter à datetime.

UPD : Encore une autre variante de la même technique:

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

Au lieu de cela, 1vous pouvez utiliser n'importe quel nombre supérieur à 0. Ici, nous utilisons le fait que datetime.fromordinalretournera toujours un datetimeobjet avec un timecomposant égal à zéro.

MarSoft
la source
6

Voilà comment je l'ai obtenu.

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)

Quelques exemples:

$ 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
la source
1
Quel est l'avantage de cela sur la réponse ci-dessus? str(datetime.timedelta(seconds=666))
Riaz Rizvi
@RiazRizvi donne une longueur de chaîne cohérente pour les microsecondes 666.0et les 666.1valeurs.
anatoly techtonik
6

L'ensemble suivant a fonctionné pour moi.

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']
décodeur naïf
la source
3

dateutil.relativedeltaest pratique si vous devez également accéder aux heures, minutes et secondes sous forme de flotteurs. datetime.timedeltane fournit pas une interface similaire.

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

Impressions

40.0
01:30:40
teekarna
la source
1
Je reçois une sortie différente de la vôtre, ce qui me fait penser que vous avez une faute de frappe. Vous vouliez probablement utiliser à la seconds=5440place de seconds=5540. J'aime bien ta réponse!
JL
2

heures (h) calculées par division du plancher (par //) de secondes par 3600 (60 min / h * 60 sec / min)

minutes (m) calculées par division au sol des secondes restantes (reste du calcul des heures, en%) par 60 (60 sec / min)

de même, secondes (s) par le reste du calcul des heures et des minutes.

Le reste n'est qu'un formatage de chaîne!

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
la source
Bien que ce code puisse fournir une solution à la question du PO, il est préférable d'ajouter du contexte pour expliquer pourquoi / comment cela fonctionne. Cela peut aider les futurs utilisateurs à apprendre et à appliquer ces connaissances à leur propre code. Vous êtes également susceptible d'avoir des commentaires positifs des utilisateurs sous la forme de votes positifs, lorsque le code est expliqué.
borchvm
2
Je viens de le faire, merci @borchvm de l'avoir signalé!
Sam
-2

Vous pouvez diviser les secondes par 60 pour obtenir les minutes

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

Lorsque vous le divisez à nouveau par 60, vous obtiendrez les heures

alosha002
la source
-3

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

PS Mon code n'est pas professionnel

Denis Kerstens Denisik35
la source
2
hé, la question demande un format en heures: min: sec, pas une simple division ..
StupidWolf