2009-04-21 7 views
298

J'ai une fonction qui retourne des informations en secondes, mais j'ai besoin de stocker cette information en heures: minutes: secondes.Comment convertir les secondes en heures, minutes et secondes?

Existe-t-il un moyen facile de convertir les secondes à ce format en python?

+11

L'inverse de ce problème peut être trouvé à [Comment convertir une chaîne de temps H: MM: SS en secondes en Python?] (Http://stackoverflow.com/questions/6402812/how-to-convert-an -hmmss-time-string-to-seconds-in-python) – hughes

Répondre

467

ou vous pouvez faire

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

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. –

+8

divmod() gagne. voir ci-dessous. – fiorix

+7

Cela échouera avec plus d'une journée de secondes. –

481

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

m, s = divmod(seconds, 60) 
h, m = divmod(m, 60) 
print "%d:%02d:%02d" % (h, m, s) 
+36

+1 pour divmod. C'est _made_ pour des situations comme celle-ci. –

+0

Je seconde la déclaration de Paolo - n'ai jamais entendu parler de divmod auparavant. Je vais devoir m'en souvenir. – Smashery

+6

J'ai édité votre réponse pour inclure un lien vers la documentation, comme il est recommandé de le faire dans la mesure du possible. –

45

Je peux nommer à peine qu'un moyen 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 la mise en forme:

>>> import time 
>>> time.strftime("%H:%M:%S", time.gmtime(666)) 
'00:11:06' 

gmtime est utilisé pour convertir les secondes en format de tuple spécial requis par strftime().

+0

Eh bien, la réponse est réellement fournie ici - http://stackoverflow.com/questions/1384406/python-convert-seconds-to-hhmmss?lq=1 –

+6

Malheureusement, cette méthode commence à mesurer les jours à partir de 1, donc il n'est pas conçu pour représenter le delta du temps, et c'est donc un accident qui attend de se produire. Par exemple avec 'time.strftime ('% d% H:% M:% S', time.gmtime (1))' => '1 jour, 0:00:01'. –

25
>>> "{:0>8}".format(datetime.timedelta(seconds=66)) 
>>> '00:01:06' # good 

et:

>>> "{:0>8}".format(datetime.timedelta(seconds=666777)) 
>>> '7 days, 17:12:57' # nice 

sans ': 0> 8':

>>> "{}".format(datetime.timedelta(seconds=66)) 
>>> '0:01:06' # not HH:MM:SS 

et:

>>> time.strftime("%H:%M:%S", time.gmtime(666777)) 
>>> '17:12:57' # wrong 

mais:

>>> "{:0>8}".format(datetime.timedelta(seconds=620000)) 
>>> '7 days, 4:13:20' # bummer 
+1

il échoue si le delta est inférieur à une seconde: '" {: 0> 8} ". Format (timedelta (millisecondes = 66)) '0: 00: 00.066000'' – jfs

+1

Pour tout le monde: Le' sans': 0> 8 ': 'il manque un zéro 0.' {: 0> 8} 'zéro pour les 8 zéros de gauche. – TankorSmash

+2

En python 3.5.2, j'obtiens un TypeError. Je suis en train de formater une variable 'time.time() - start'. Un aperçu? 'TypeError: chaîne de format non vide passée à l'objet .__ format__' – medley56

2

Voici comment je l'ai eu.

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

Quel est l'avantage de ceci sur la réponse ci-dessus? 'str (datetime.timedelta (seconds = 666))' –

+0

@RiazRizvi donne une longueur de chaîne cohérente pour les microsecondes pour les valeurs '666.0' et' 666.1'. –

6

Si vous avez besoin pour obtenir datetime.time valeur, 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: Une autre variante de la même technique:

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

Au lieu de 1 vous pouvez utiliser un nombre supérieur à 0. Ici, nous utilisons le fait que datetime.fromordinal vaudra toujours objet datetime avec time composant être zéro.

Questions connexes