J'ai une fonction qui renvoie des informations en secondes, mais je dois stocker ces informations en heures: minutes: secondes.
Existe-t-il un moyen facile de convertir les secondes en ce format en Python?
J'ai une fonction qui renvoie des informations en secondes, mais je dois stocker ces informations en heures: minutes: secondes.
Existe-t-il un moyen facile de convertir les secondes en ce format en Python?
Réponses:
Vous pouvez utiliser la datetime.timedelta
fonction:
>>> 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)))
rend correctement les jours; supprime les secondes décimales.
timedelta
n'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'
.
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+
'%d:%02dmn' % (seconds / 60, seconds % 60)
d, h = divmod(h, 24)
.
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 timedelta
le calendrier et ne le dérangez pas, il vous mordra.
timedelta
les secondes intercalaires ? Je suppose que non. Il existe de nombreuses applications où ce calcul simple est plus que suffisant.
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.
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
time.strftime('%d %H:%M:%S', time.gmtime(1))
=> '1 jour, 0:00:01'.
datetime
:':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'
':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'
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':
exemple, il manque un 0. {:0>8}
zéro zéro en tête pour les 8 zéros à gauche.
time.time()-start
variable. Un aperçu? TypeError: non-empty format string passed to object.__format__
datetime.now()
au lieu de time.time()
pour générer mon objet timedelta et j'obtiens la même erreur.
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.
Voici ma petite astuce:
from humanfriendly import format_timespan
secondsPassed = 1302
format_timespan(secondsPassed)
# '21 minutes and 42 seconds'
Pour plus d'informations, visitez: https://humanfriendly.readthedocs.io/en/latest/#humanfriendly.format_timespan
Si vous avez besoin d'obtenir de la 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 : Encore une autre variante de la même technique:
my_time = (datetime.fromordinal(1) + timedelta(seconds=my_seconds)).time()
Au lieu de cela, 1
vous pouvez utiliser n'importe quel nombre supérieur à 0. Ici, nous utilisons le fait que datetime.fromordinal
retournera toujours un datetime
objet avec un time
composant égal à zéro.
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']
str(datetime.timedelta(seconds=666))
666.0
et les 666.1
valeurs.
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']
dateutil.relativedelta
est pratique si vous devez également accéder aux heures, minutes et secondes sous forme de flotteurs. datetime.timedelta
ne 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
seconds=5440
place de seconds=5540
. J'aime bien ta réponse!
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
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