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

- je obtenir un date_debut comme ceci:

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 obtenir une sortie comme ceci:

datetime.timedelta(0, 5, 41038)

Comment puis-je convertir ceci en temps normal comme:

10 minutes, 1 heure comme ceci

31
demandé sur user1881957 2013-01-07 08:48:07

7 réponses

il n'y a pas de formatteur intégré pour timedelta objets, mais c'est assez facile de le faire soi-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 êtes dans Python 2.7+ 3,2+:

seconds = duration.total_seconds()
hours = seconds // 3600
minutes = (seconds % 3600) // 60
seconds = seconds % 60

Maintenant vous pouvez l'imprimer comme vous voulez:

'{} 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)

imprimer:

9 minutes, 50 hours

Si vous souhaitez obtenir des "10 minutes, 1 heure" au lieu de "10 minutes, 1 heure", vous devez le faire manuellement trop:

print '{} minute{}, {} hour{}'.format(minutes, 's' if minutes != 1 else '',
                                      hours, 's' if minutes != 1 else '')

Ou vous pouvez écrire un english_plural fonction pour faire l' 's' bits pour vous, au lieu de se répéter.

D'après vos commentaires, On dirait que vous voulez réellement garder les jours séparés. C'est encore plus simple:

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 ceci en une valeur unique pour stocker dans une base de données, puis convertir cette valeur unique de nouveau pour le formater, faites ceci:

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, de les mettre 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)
72
répondu abarnert 2013-01-07 05:50:19

datetime.timedelta correspond à différence entre deux dates, pas une date elle-même. C'est seulement exprimé en jours, secondes, et microsecondes, puisque les unités de temps plus grandes comme les mois et les années ne se décomposent pas proprement (est de 30 jours 1 mois ou 0,9677 mois?).

Si vous voulez convertir un timedelta EN heures et minutes, vous pouvez utiliser le total_seconds() méthode pour obtenir le nombre total de secondes et ensuite faire quelques maths:

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
répondu Adam Rosenfield 2013-01-07 05:04:27

il n'y a pas besoin de fonctions d'aide personnalisées si tout ce que nous avons besoin est d'Imprimer la chaîne de la forme [D day[s], ][H]H:MM:SS[.UUUUUU]. timedelta support d'objet str() opération qui fera ceci. Il 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'
4
répondu wombatonfire 2017-05-14 14:33:57

il suffit d'utiliser strftime:)

quelque Chose comme ça:

my_date = datetime.datetime(2013, 1, 7, 10, 31, 34, 243366, tzinfo=<UTC>)
print(my_date.strftime("%Y, %d %B"))

après avoir édité 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
1
répondu Infinity 2013-01-07 05:03:51

j'ai défini propre fonction d'aide pour convertir l'objet timedelta au format' HH:MM:SS ' - seulement des heures, des minutes et des secondes, sans changer des 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
répondu MobilePro.pl 2016-03-03 08:29:54

voulez-vous imprimer la date dans ce format? C'est le python doc: 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 les 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 liée. Pour les cas ci-dessus, il n'a pas les heures et la valeur de minute, Vous devriez calculer à partir des secondes.

0
répondu jinghli 2013-01-07 05:09:02
datetime.timedelta(hours=1, minutes=10)
#python 2.7
-3
répondu user5435345 2015-10-15 01:22:07