como - Python: diferencia de 2 fechas en meses
como hacer un calendario en python (4)
La ventaja de hacerlo de esta manera es que hay pocas dependencias de módulos y ningún bucle: los meses se pueden encontrar mediante cálculo directo.
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
Posible duplicado:
La mejor forma de encontrar los meses entre dos fechas (en python)
Me gustaría saber cómo puedo tener el número exacto de meses para esta diferencia:
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 resultados en
datetime.timedelta(183, 43200)
Me gustaría saber el número exacto de meses, en este caso debería devolver 5 y no 6 (debido a la hora)
Podría usar 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)
Solo usted conoce los requisitos que debe cumplir, pero el hecho de que haya 183 días y 43200 segundos SI entre estas dos fechas resalta una subjetividad inherente en la determinación de cuántos meses ese "realmente" es.
¿Es un mes de 30 días, o (365/12) días, o ((365 * 4 + 1) / 48) días, o ...?
¿Es un día siempre de 86400 segundos o cuenta segundos intercalares históricos o predice segundos intercalares para fechas futuras?
Estas decisiones afectan la respuesta que el algoritmo que parezca desear le dará para ciertas fechas de entrada que están cerca de estos límites.
En mi opinión, es más intuitivo considerar meses como unidades atómicas de tiempo para este propósito y usar esta fórmula: (date2.year - date1.year) * 12 + (date2.month - date1.month)
Usando el módulo de calendar
para averiguar cuántos días tiene cada mes, simplemente puede contar los meses.
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