web-dev-qa-db-fra.com

Python: différence de 2 heures en mois

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)

37
Tiago Moutinho

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
24
Senko Rašić

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)
70
sandinmyjoints

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)

22
wberry

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
5
unutbu