Je reçois une date de début comme celle-ci:
from Django.utils.timezone import utc
import datetime
start_date = datetime.datetime.utcnow().replace(tzinfo=utc)
end_date = datetime.datetime.utcnow().replace(tzinfo=utc)
duration = end_date - start_date
Je reçois une sortie comme ceci:
datetime.timedelta(0, 5, 41038)
Comment puis-je convertir ceci en temps normal comme suit?
10 minutes, 1 heure comme ça
Il n'y a pas de formateur intégré pour les objets timedelta
, mais il est assez facile de le faire vous-même:
days, seconds = duration.days, duration.seconds
hours = days * 24 + seconds // 3600
minutes = (seconds % 3600) // 60
seconds = seconds % 60
Ou, de manière équivalente, si vous utilisez Python 2.7+ ou 3.2+:
seconds = duration.total_seconds()
hours = seconds // 3600
minutes = (seconds % 3600) // 60
seconds = seconds % 60
Maintenant, vous pouvez l’imprimer comme vous le souhaitez:
'{} minutes, {} hours'.format(minutes, hours)
Par exemple:
def convert_timedelta(duration):
days, seconds = duration.days, duration.seconds
hours = days * 24 + seconds // 3600
minutes = (seconds % 3600) // 60
seconds = (seconds % 60)
return hours, minutes, seconds
td = datetime.timedelta(2, 7743, 12345)
hours, minutes, seconds = convert_timedelta(td)
print '{} minutes, {} hours'.format(minutes, hours)
Cela va imprimer:
9 minutes, 50 hours
Si vous voulez obtenir "10 minutes, 1 heure" au lieu de "10 minutes, 1 heures", vous devez le faire manuellement aussi:
print '{} minute{}, {} hour{}'.format(minutes, 's' if minutes != 1 else '',
hours, 's' if minutes != 1 else '')
Ou vous pouvez écrire une fonction english_plural
pour créer les bits 's'
à votre place, au lieu de vous répéter.
D'après vos commentaires, il semble que vous souhaitiez réellement séparer les jours. C'est encore plus facile:
def convert_timedelta(duration):
days, seconds = duration.days, duration.seconds
hours = seconds // 3600
minutes = (seconds % 3600) // 60
seconds = (seconds % 60)
return days, hours, minutes, seconds
Si vous voulez convertir cela en une valeur unique à stocker dans une base de données, puis reconvertissez cette valeur unique pour la formater, procédez comme suit:
def dhms_to_seconds(days, hours, minutes, seconds):
return (((days * 24) + hours) * 60 + minutes) * 60 + seconds
def seconds_to_dhms(seconds):
days = seconds // (3600 * 24)
hours = (seconds // 3600) % 24
minutes = (seconds // 60) % 60
seconds = seconds % 60
return days, hours, minutes, seconds
Donc, en le mettant ensemble:
def store_timedelta_in_database(thingy, duration):
seconds = dhms_to_seconds(*convert_timedelta(duration))
db.execute('INSERT INTO foo (thingy, duration) VALUES (?, ?)',
thingy, seconds)
db.commit()
def print_timedelta_from_database(thingy):
cur = db.execute('SELECT duration FROM foo WHERE thingy = ?', thingy)
seconds = int(cur.fetchone()[0])
days, hours, minutes, seconds = seconds_to_dhms(seconds)
print '{} took {} minutes, {} hours, {} days'.format(thingy, minutes, hours, days)
Un datetime.timedelta
correspond à la difference entre deux dates et non à une date elle-même. Elle n'est exprimée qu'en jours, secondes et microsecondes, car les unités de temps plus grandes comme les mois et les années ne se décomposent pas proprement (30 jours sur 1 mois ou 0,9677 mois?).
Si vous voulez convertir une timedelta
en heures et en minutes, vous pouvez utiliser la méthode total_seconds()
pour obtenir le nombre total de secondes, puis faire quelques calculs:
x = datetime.timedelta(1, 5, 41038) # Interval of 1 day and 5.41038 seconds
secs = x.total_seconds()
hours = int(secs / 3600)
minutes = int(secs / 60) % 60
Des fonctions d'assistance personnalisées ne sont pas nécessaires si tout ce dont nous avons besoin est d'imprimer la chaîne de caractères du formulaire [D day[s], ][H]H:MM:SS[.UUUUUU]
. timedelta object supporte l'opération str()
qui le fera. Cela fonctionne même en Python 2.6.
>>> from datetime import timedelta
>>> timedelta(seconds=90136)
datetime.timedelta(1, 3736)
>>> str(timedelta(seconds=90136))
'1 day, 1:02:16'
Il suffit d'utiliser strftime :)
Quelque chose comme ca:
my_date = datetime.datetime(2013, 1, 7, 10, 31, 34, 243366, tzinfo=<UTC>)
print(my_date.strftime("%Y, %d %B"))
Après avoir modifié votre question au format timedelta
, vous pouvez utiliser:
def timedelta_Tuple(timedelta_object):
return timedelta_object.days, timedelta_object.seconds//3600, (timedelta_object.seconds//60)%60
J'ai défini sa propre fonction d'assistance pour convertir l'objet timedelta au format 'HH: MM: SS' - uniquement en heures, minutes et secondes, sans changer les heures en jours.
def format_timedelta(td):
hours, remainder = divmod(td.total_seconds(), 3600)
minutes, seconds = divmod(remainder, 60)
hours, minutes, seconds = int(hours), int(minutes), int(seconds)
if hours < 10:
hours = '0%s' % int(hours)
if minutes < 10:
minutes = '0%s' % minutes
if seconds < 10:
seconds = '0%s' % seconds
return '%s:%s:%s' % (hours, minutes, seconds)
Voulez-vous imprimer la date dans ce format? Voici la documentation Python: http://docs.python.org/2/library/datetime.html#strftime-strptime-behavior
>>> a = datetime.datetime(2013, 1, 7, 10, 31, 34, 243366)
>>> print a.strftime('%Y %d %B, %M:%S%p')
>>> 2013 07 January, 31:34AM
Pour le timedelta:
>>> a = datetime.timedelta(0,5,41038)
>>> print '%s seconds, %s microseconds' % (a.seconds, a.microseconds)
Mais s'il vous plaît noter, vous devriez vous assurer qu'il a la valeur connexe. Pour les cas ci-dessus, il n'a pas les heures et les minutes, et vous devriez calculer à partir des secondes.
Je ne pense pas que ce soit une bonne idée de se calculer.
Si vous voulez juste une jolie sortie, convertissez-la simplement en str
avec la fonction str()
ou directement print()
le.
Et si les heures et les minutes sont utilisées davantage, vous pouvez l'analyser avec l'objet datetime
, utiliser datetime.strptime()
(et extraire la partie temporelle avec datetime.time()
mehtod), par exemple:
import datetime
delta = datetime.timedelta(seconds=10000)
time_obj = datetime.datetime.strptime(str(delta),'%H:%M:%S').time()