web-dev-qa-db-fra.com

Python - Comparaison de date et d'heure à l'aide d'horodatages, timedelta

J'ai passé la dernière heure à fouiller dans les documents Python et de nombreuses questions SO; veuillez me pardonner d'être un autre Python = débutant piégé par le mystère du décalage horaire en Python.

Mon objectif est de déterminer la différence entre l'heure actuelle et une certaine date/heure indépendamment du fait d'être dans le passé/futur et retourner un format exploitable tel que les secondes.

Par exemple, si les entrées sont 14 h 00 et 16 h 00 (maintenant), j'aimerais qu'il dise "-7200", représentant l'événement survenu il y a deux heures AGO. Si les entrées sont le vendredi 16 h 00 (maintenant) et le dimanche 17 h 00, la sortie doit être "176400" secondes, soit deux jours et 1 heure à partir de maintenant.

Voici les choses que j'ai essayées ...

  • Ma première version était une fonction qui prenait un horodatage de chaîne et l'associait à plusieurs variables, puis les comparait. C'était maladroit avec beaucoup d'erreurs et j'imagine que si je le publiais ici, je serais responsable d'un vomissement des programmeurs.

  • Je suis tombé sur cette fonction de timedelta magique et j'ai exploré les documents et SO, mais je ne pense pas que cela fasse ce que je recherche.

  • J'ai eu l'idée de convertir les deux horodatages en secondes depuis Epoch puis de soustraire, mais cela devient un problème si la soustraction est dans le mauvais ordre (différents cas si l'événement est dans le futur), et j'ai envie d'ajouter des instructions if à vérifier le signe des secondes serait maladroit et quelque chose à éviter.

Ceci est mon code actuel (doit encore être corrigé pour une comparaison 'bidirectionnelle'), à partir d'une question SO:

now = time.strftime("%a %b %d %H:%M:%S %Y")
then = time.ctime(os.path.getmtime("x.cache"))
tdelta = datetime.strptime(now, '%a %b %d %H:%M:%S %Y') - datetime.strptime(then, '%a %b %d %H:%M:%S %Y')

Et je pense que je devrais être en mesure de tirer des secondes de cela, comme dans cette question: timedelta de Python: ne puis-je pas simplement entrer dans l'unité de temps dont je veux la valeur de la différence entière?

Mais je ne sais pas trop comment connecter ces points.

Comment puis-je accomplir cela?

19
daltonf

Vous devriez pouvoir utiliser

tdelta.total_seconds()

pour obtenir la valeur que vous recherchez. Cela est dû au fait que tdelta est un objet timedelta , de même que toute différence entre les objets datetime.

Quelques notes:

  1. Utiliser strftime suivi de strptime est superflu. Vous devriez pouvoir obtenir l'heure actuelle avec datetime.now .
  2. De même, en utilisant time.ctime suivi de strptime est plus de travail que nécessaire. Vous devriez pouvoir obtenir l'autre datetime objet avec datetime.fromtimestamp .

Donc, votre code final pourrait être

now = datetime.now()
then = datetime.fromtimestamp(os.path.getmtime("x.cache"))
tdelta = now - then
seconds = tdelta.total_seconds()
28
murgatroid99

Quel est le problème avec cette méthode?

>>> from datetime import datetime
>>> a = datetime.now()
>>> b = datetime.now() # after a few seconds
>>> delta = a-b
>>> delta.total_seconds()
-6.655989

Notez que total_seconds n'est disponible qu'en Python 2.7 <, mais selon la documentation:

Équivalent à (td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) / 10**6 calculé avec la vraie division activée.

ce qui donne exactement le même résultat.

9
Yuval Adam

J'ai eu le même problème il y a quelques mois. Ce que vous recherchez est datetime.timedelta et datetime.datetime.fromtimestamp (). Voici un exemple pour savoir comment les utiliser pour résoudre votre problème.

import datetime
import time
t1 = time.time()
#do something to kill time or get t2 from somewhere
a = [i for i in range(1000)]
t2 = time.time()
#get the difference as datetime.timedelta object
diff=(datetime.datetime.fromtimestamp(t1) - datetime.datetime.fromtimestamp(t2))
#diff is negative as t2 is in the future compared to t2
print('difference is {0} seconds'.format(abs(diff.total_seconds())))
2
MHardy