Convertir un timedelta en jours, heures et minutes

243

J'ai un timedelta. Je veux les jours, les heures et les minutes de cela - soit comme un tuple ou un dictionnaire ... Je ne suis pas embêté.

J'ai dû le faire une douzaine de fois dans une douzaine de langues au fil des ans, mais Python a généralement une réponse simple à tout, alors j'ai pensé que je demanderais ici avant d'éclater des mathématiques d'une simplicité nauséabonde (mais verbeuse).

M. Fooz soulève un bon point.

J'ai affaire à des "listes" (un peu comme les listes ebay) où chacune a une durée. J'essaye de trouver le temps qui reste en faisantwhen_added + duration - now

Ai-je raison de dire que cela ne rendrait pas compte de l'heure d'été? Sinon, quelle est la manière la plus simple d'ajouter / de soustraire une heure?

Oli
la source
Si c'est juste pour l'obtenir sous forme de chaîne au format HH: mm: ss, dites "0:19:37" de l' timedeltaobjet "datetime.timedelta (seconds = 1177)" : utilisez
Peter Mortensen

Réponses:

344

Si vous avez une datetime.timedeltavaleur td, td.daysvous donne déjà les "jours" que vous souhaitez. timedeltales valeurs restent fraction de jour sous forme de secondes (pas directement des heures ou des minutes), vous devrez donc effectuer des "mathématiques d'une simplicité nauséabonde", par exemple:

def days_hours_minutes(td):
    return td.days, td.seconds//3600, (td.seconds//60)%60
Alex Martelli
la source
1
Gardez à l'esprit que si tdest négatif, l' -1 // 3600est -1.
jcrs
4
Pourquoi // ? au lieu de /
Mohammed Shareef C
10
//est utilisé à la place de /pour obtenir un entier, pas un flottant. //est un opérateur de division d'étage: "division qui se traduit par un nombre entier ajusté à gauche dans la droite numérique", voir ici .
Eerik Sven Puudist
1
@EerikSvenPuudist comme jcrsindiqué, -1//3600est -1, alors pourquoi ne pas utiliser à la int(td.seconds/3600)place pour transformer la -1seconde en 0heures plutôt qu'en 1heure en arrière?
simpleuser
que diriez-vous d'ajouter les secondes restantes aussi? days, hours, minutes = x.days, x.seconds // 3600, x.seconds %3600//60puis seconds = x.seconds - hours*3600 - minutes*60
raphael
73

C'est un peu plus compact, vous obtenez les heures, les minutes et les secondes sur deux lignes.

days = td.days
hours, remainder = divmod(td.seconds, 3600)
minutes, seconds = divmod(remainder, 60)
# If you want to take into account fractions of a second
seconds += td.microseconds / 1e6
mberacochea
la source
7
il est incorrect s'il td.daysest différent de zéro. Vous en avez besoin hours += td.days*24. Si vous voulez prendre en compte des fractions de seconde (OP ne le fait pas); seconds += td.microseconds / 1e6peut être utilisé.
jfs
30
days, hours, minutes = td.days, td.seconds // 3600, td.seconds // 60 % 60

Quant à l'heure d'été, je pense que la meilleure chose est de convertir les deux datetimeobjets en secondes. De cette façon, le système calcule l'heure d'été pour vous.

>>> m13 = datetime(2010, 3, 13, 8, 0, 0)  # 2010 March 13 8:00 AM
>>> m14 = datetime(2010, 3, 14, 8, 0, 0)  # DST starts on this day, in my time zone
>>> mktime(m14.timetuple()) - mktime(m13.timetuple())     # difference in seconds
82800.0
>>> _/3600                                                # convert to hours
23.0
Jason Orendorff
la source
1
mktime()peut échouer si le fuseau horaire local peut avoir un décalage utc différent à différents moments (beaucoup le font) - vous pouvez utiliser le pytzmodule pour accéder à la base de données tz de manière détéministe portable. En outre, l'heure locale peut être ambiguë (50% de chances d'une erreur) - vous avez besoin d'informations supplémentaires pour lever l'ambiguïté, par exemple, souvent (pas toujours) les dates dans un fichier journal sont monotones . Voir Comment puis-je soustraire un jour d'une date python? qui peuvent avoir à faire face à des problèmes similaires.
jfs
7

Je ne comprends pas

days, hours, minutes = td.days, td.seconds // 3600, td.seconds // 60 % 60

que dis-tu de ça

days, hours, minutes = td.days, td.seconds // 3600, td.seconds % 3600 / 60.0

Vous obtenez des minutes et des secondes d'une minute comme un flotteur.

campbell
la source
0

J'ai utilisé ce qui suit:

delta = timedelta()
totalMinute, second = divmod(delta.seconds, 60)
hour, minute = divmod(totalMinute, 60)
print(f"{hour}h{minute:02}m{second:02}s")
Mathieu CAROFF
la source
-3

les timedeltas ont un attribut dayset seconds.. vous pouvez les convertir vous-même facilement.

Jochen Ritzel
la source