Duplicata possible:
Meilleure façon de trouver les mois entre deux dates (en python)
Je voudrais savoir comment je peux avoir le nombre exact de mois pour cette différence:
date1 = datetime.strptime(str('2011-08-15 12:00:00'), '%Y-%m-%d %H:%M:%S')
date2 = datetime.strptime(str('2012-02-15'), '%Y-%m-%d')
date2-date1 se traduit par
datetime.timedelta(183, 43200)
Je voudrais connaître le nombre exact de mois, dans ce cas il devrait retourner 5 et non 6 (à cause de l'heure)
En utilisant le module calendar
pour connaître le nombre de jours par mois, vous pouvez simplement compter les mois.
from calendar import monthrange
from datetime import datetime, timedelta
def monthdelta(d1, d2):
delta = 0
while True:
mdays = monthrange(d1.year, d1.month)[1]
d1 += timedelta(days=mdays)
if d1 <= d2:
delta += 1
else:
break
return delta
Vous pouvez utiliser python-dateutil .
In [4]: from datetime import datetime
In [5]: date1 = datetime.strptime(str('2011-08-15 12:00:00'), '%Y-%m-%d %H:%M:%S')
In [6]: date2 = datetime.strptime(str('2012-02-15'), '%Y-%m-%d')
In [7]: from dateutil import relativedelta
In [8]: r = relativedelta.relativedelta(date1, date2)
In [9]: r
Out[9]: relativedelta(months=-5, days=-30, hours=-12)
Vous seul connaissez les exigences que vous devez satisfaire, mais le fait qu'il y ait 183 jours et 43200 secondes SI entre ces deux dates met en évidence une subjectivité inhérente à la détermination du nombre de mois "réellement".
Est-ce qu'un mois est de 30 jours, ou (365/12) jours, ou ((365 * 4 + 1)/48) jours, ou ...?
Un jour est-il toujours 86400 secondes, ou comptez-vous les secondes intercalaires historiques, ou prévoyez-vous des secondes intercalaires pour les dates futures?
Ces décisions affectent la réponse que l'algorithme que vous semblez vouloir vous donner pour certaines dates d'entrée proches de ces limites.
À mon avis, il est plus intuitif de considérer les mois comme des unités de temps atomiques à cette fin et d'utiliser cette formule: (date2.year - date1.year) * 12 + (date2.month - date1.month)
L'avantage de procéder de cette façon est qu'il y a peu de dépendances de module et pas de boucle - les mois peuvent être trouvés par un calcul simple.
import datetime as dt
def months_between(date1,date2):
if date1>date2:
date1,date2=date2,date1
m1=date1.year*12+date1.month
m2=date2.year*12+date2.month
months=m2-m1
if date1.day>date2.day:
months-=1
Elif date1.day==date2.day:
seconds1=date1.hour*3600+date1.minute+date1.second
seconds2=date2.hour*3600+date2.minute+date2.second
if seconds1>seconds2:
months-=1
return months
date1 = dt.datetime.strptime('2011-08-15 12:00:00', '%Y-%m-%d %H:%M:%S')
date2 = dt.datetime.strptime('2012-02-15', '%Y-%m-%d')
print(months_between(date1,date2))
# 5
date1 = dt.datetime.strptime('2011-08-15 12:00:00', '%Y-%m-%d %H:%M:%S')
date2 = dt.datetime.strptime('2012-02-15 11:59:00', '%Y-%m-%d %X')
print(months_between(date1,date2))
# 5
date2 = dt.datetime.strptime('2012-02-15 12:00:00', '%Y-%m-%d %X')
print(months_between(date1,date2))
# 6
date2 = dt.datetime.strptime('2012-02-15 12:00:01', '%Y-%m-%d %X')
print(months_between(date1,date2))
# 6