web-dev-qa-db-fra.com

Comment convertir datetime.timedelta en minutes, en heures en Python?

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

36
user1881957

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

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
16
Adam Rosenfield

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'
6
wombatonfire

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
2
Infinity

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)
1
MobilePro.pl

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.

0
jinghli

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()
0
C.K.