¿Cómo calculo la fecha seis meses después de la fecha actual usando el módulo Python datetime?

391

Estoy usando el módulo de fecha y hora de Python. Estoy buscando calcular la fecha 6 meses a partir de la fecha actual. ¿Podría alguien darme un poco de ayuda para hacer esto?

La razón por la que quiero generar una fecha 6 meses después de la fecha actual es para producir una fecha de revisión . Si el usuario ingresa datos en el sistema, tendrá una fecha de revisión de 6 meses a partir de la fecha en que ingresó los datos.

CarrilesHijo
fuente
2
Tendrás que ser más específico: ¿cuándo son seis meses a partir del 31 de marzo? ¿Y a partir del 30 de agosto?
kmkaplan
3
Sí, la edición ayuda: significa que puede aproximarse de 6 meses a 183 días sin ningún efecto negativo. Por lo tanto, agregar 183 días para hoy hará el truco.
kmkaplan
15
Los comentarios anteriores me parecen tontos. El concepto de "agregar seis meses" es bastante claro: tome el componente del mes y agréguelo 6, con soporte para pasar el año (y volver al mes 1) si pasamos diciembre. Esto es exactamente lo que relativedeltahace y es, de hecho, lo que hace cada lenguaje de programación con soporte para este tipo de concepto.
Kirk Woll
55
@ KirkWoll: Estoy seguro de que está bastante claro. Pero sigue siendo diferente para quien habla. Python: date(2015, 3, 31) + relativedelta(months = 6)da datetime.date(2015, 9, 30). Perl: DateTime->new(year=>2000, month=>3, day=>31)->add(months=>6)da 2000-10-01T00:00:00. Php: date_create('2000-03-31', new DateTimeZone('UTC'))->add(new DateInterval('P6M'))da 2000-10-01. Elige tu veneno.
kmkaplan
2
... agregar 182 parece más pragmático para generar una fecha de revisión : mantiene intacto el día de la semana.
Wolf

Respuestas:

1047

Encontré que esta solución es buena. (Esto usa la extensión python-dateutil )

from datetime import date
from dateutil.relativedelta import relativedelta

six_months = date.today() + relativedelta(months=+6)

La ventaja de este enfoque es que se ocupa de los problemas con 28, 30, 31 días, etc. Esto se vuelve muy útil en el manejo de reglas y escenarios comerciales (por ejemplo, generación de facturas, etc.)

$ date(2010,12,31)+relativedelta(months=+1)
  datetime.date(2011, 1, 31)

$ date(2010,12,31)+relativedelta(months=+2)
  datetime.date(2011, 2, 28)
Mahendra
fuente
2
el +6 es un indicador de que podría ser -6, lo mismo se aplica a días y años también :)
securecurve
55
@sliders_alpha Necesita instalar el paquete python-dateutil (pip install python-dateutil)
poiuytrez
18
Esta es la solución correcta. Si el OP hubiera pedido 6 años en lugar de 6 meses, entonces la respuesta aprobada fallaría miserablemente. Por lo tanto, uno debe tener en cuenta que las respuestas son más valiosas cuanto más generalizadas son.
Daniel F
3
Tenga en cuenta que la relativedeltafunción también toma monthcomo argumento, que básicamente reemplaza / establece / arregla el mes en la fecha aprobada, que es muy diferente a agregar más meses. Solo una advertencia para las personas que se preguntan si la función está rota porque olvidaron los s adicionales en meses .
shad0w_wa1k3r
1
Tengo curiosidad: ¿alguien sabe por qué esto no está incluido por defecto? Timedelta parece empaquetado datetimepor defecto. De hecho, supuse que podía pasar "meses" en timedelta.
dTanMan
51

Bueno, eso depende de lo que quieras decir con 6 meses a partir de la fecha actual.

  1. Usando meses naturales:

    (day, month, year) = (day, (month + 5) % 12 + 1, year + (month + 5)/12)
  2. Usando la definición de un banquero, 6 * 30:

    date += datetime.timedelta(6 * 30)
vartec
fuente
3
¿Podría incluir también la definición de medio año (183 días) más la definición de 26 semanas? Es útil tenerlos a todos en un solo lugar.
S.Lott
11
solo un comentario rápido: creo que, para el mes, la fórmula sería (mes + 5)% 12 + 1 b / c para junio, su fórmula da 0 mientras que el resultado esperado es 12 ... a pesar de este pequeño error, a mi mente, tu respuesta es la que mejor responde la pregunta
PierrOz
3
y lo mismo para el año: debería ser año + (mes + 5) / 12
PierrOz
77
¿Qué sucede si la fecha es 31 y el mes seis meses después no puede tener 31 días (que es el caso para la mayoría de los meses con 31 días)?
akv
44
Voto negativo porque la primera solución (day, month, year) = (day, (month+6)%12, year+(month+6)/12)puede tener errores, ya que genera fechas no válidas como (31, 8, 2015)->(31, 2, 2016)
ohw
37

Con Python 3.x puedes hacerlo así:

from datetime import datetime, timedelta
from dateutil.relativedelta import *

date = datetime.now()
print(date)
# 2018-09-24 13:24:04.007620

date = date + relativedelta(months=+6)
print(date)
# 2019-03-24 13:24:04.007620

pero necesitará instalar el módulo python-dateutil :

pip install python-dateutil
Luka Lopusina
fuente
Votado a favorpip install ...
Nathan
Me gustaría recomendar from dateutil.relativedelta import relativedelta. El uso import *no es explícito.
Sam Morgan
19

Para el inicio del cálculo de mes a mes:

from datetime import timedelta
from dateutil.relativedelta import relativedelta

end_date = start_date + relativedelta(months=delta_period) + timedelta(days=-delta_period)
breddi
fuente
18
Esta no es la solución relativadelta mencionada anteriormente en los comentarios. Sigue buscando la solución con más de 600 votos a favor.
Nostalg.io
15

¿Qué quieres decir con "6 meses"?

¿Es 2009-02-13 + 6 meses == 2009-08-13? ¿O es 2009-02-13 + 6 * 30 días?

import mx.DateTime as dt

#6 Months
dt.now()+dt.RelativeDateTime(months=6)
#result is '2009-08-13 16:28:00.84'

#6*30 days
dt.now()+dt.RelativeDateTime(days=30*6)
#result is '2009-08-12 16:30:03.35'

Más información sobre mx.DateTime

Johannes Weiss
fuente
14

Entonces, aquí hay un ejemplo de dateutil.relativedeltalo que encontré útil para iterar durante el año pasado, omitiendo un mes cada vez hasta la fecha actual:

>>> import datetime
>>> from dateutil.relativedelta import relativedelta
>>> today = datetime.datetime.today()
>>> month_count = 0
>>> while month_count < 12:
...  day = today - relativedelta(months=month_count)
...  print day
...  month_count += 1
... 
2010-07-07 10:51:45.187968
2010-06-07 10:51:45.187968
2010-05-07 10:51:45.187968
2010-04-07 10:51:45.187968
2010-03-07 10:51:45.187968
2010-02-07 10:51:45.187968
2010-01-07 10:51:45.187968
2009-12-07 10:51:45.187968
2009-11-07 10:51:45.187968
2009-10-07 10:51:45.187968
2009-09-07 10:51:45.187968
2009-08-07 10:51:45.187968

Al igual que con las otras respuestas, debe averiguar qué quiere decir realmente con "6 meses a partir de ahora". Si quiere decir "el día de hoy del mes en el mes seis años en el futuro", esto haría:

datetime.datetime.now() + relativedelta(months=6)
dannyman
fuente
14

Esta solución funciona correctamente para diciembre, lo que la mayoría de las respuestas en esta página no. Primero debe cambiar los meses de la base 1 (es decir, Jan = 1) a la base 0 (es decir, Jan = 0) antes de usar el módulo (%) o la división entera (//), de lo contrario, noviembre (11) más 1 mes le da 12 , que al encontrar el resto (12% 12) da 0.

(¡Y no sugiera "(mes% 12) + 1" u Oct + 1 = diciembre!)

def AddMonths(d,x):
    newmonth = ((( d.month - 1) + x ) % 12 ) + 1
    newyear  = int(d.year + ((( d.month - 1) + x ) / 12 ))
    return datetime.date( newyear, newmonth, d.day)

Sin embargo ... Esto no tiene en cuenta un problema como el 31 de enero + un mes. Entonces volvemos al OP: ¿qué quiere decir con agregar un mes? Una solución es retroceder hasta llegar a un día válido, dado que la mayoría de las personas presumirían que el último día de enero, más un mes, es igual al último día de febrero. Esto también funcionará en números negativos de meses. Prueba:

>>> import datetime
>>> AddMonths(datetime.datetime(2010,8,25),1)
datetime.date(2010, 9, 25)
>>> AddMonths(datetime.datetime(2010,8,25),4)
datetime.date(2010, 12, 25)
>>> AddMonths(datetime.datetime(2010,8,25),5)
datetime.date(2011, 1, 25)
>>> AddMonths(datetime.datetime(2010,8,25),13)
datetime.date(2011, 9, 25)
>>> AddMonths(datetime.datetime(2010,8,25),24)
datetime.date(2012, 8, 25)
>>> AddMonths(datetime.datetime(2010,8,25),-1)
datetime.date(2010, 7, 25)
>>> AddMonths(datetime.datetime(2010,8,25),0)
datetime.date(2010, 8, 25)
>>> AddMonths(datetime.datetime(2010,8,25),-12)
datetime.date(2009, 8, 25)
>>> AddMonths(datetime.datetime(2010,8,25),-8)
datetime.date(2009, 12, 25)
>>> AddMonths(datetime.datetime(2010,8,25),-7)
datetime.date(2010, 1, 25)>>> 
usuario417751
fuente
3
Soluciona el problema "31 de enero + un mes": days_in_month = calendar.monthrange (newyear, newmonth) [1]; newday = min (d.day, days_in_month); (baja el día si es demasiado grande, por ejemplo, 31 de febrero al 28/29 de febrero)
Curtis Yallop
Esto funcionó para mí solo al convertir el año nuevo a un tipo de datos entero def AddMonths (d, x): newmonth = (((d.month - 1) + x)% 12) + 1 newyear = d.year + int (( (d.month - 1) + x) / 12) return datetime.date (newyear, newmonth, d.day)
Manmeet Singh
12

Sé que esto fue durante 6 meses, sin embargo, la respuesta se muestra en Google para "agregar meses en Python" si agrega un mes:

import calendar

date = datetime.date.today()    //Or your date

datetime.timedelta(days=calendar.monthrange(date.year,date.month)[1])

esto contaría los días en el mes actual y los agregaría a la fecha actual, el uso de 365/12 podría agregar 1/12 de un año puede causar problemas durante meses cortos / largos si está iterando durante la fecha.

Mike Davies
fuente
11

No hay forma directa de hacerlo con la fecha y hora de Python.

Echa un vistazo al tipo relativo delta en python-dateutil . Le permite especificar un delta de tiempo en meses.

Akbar ibrahim
fuente
10

Simplemente use el método timetuple para extraer los meses, agregar sus meses y crear un nuevo objeto de fecha. Si ya existe un método para esto, no lo sé.

import datetime

def in_the_future(months=1):
    year, month, day = datetime.date.today().timetuple()[:3]
    new_month = month + months
    return datetime.date(year + (new_month / 12), (new_month % 12) or 12, day)

La API es un poco torpe, pero funciona como un ejemplo. Obviamente, tampoco funcionará en casos de esquina como 2008-01-31 + 1 mes. :)

Pi.
fuente
3
Error en su código: new_month % 12debería ser (new_month % 12) or 12. De lo contrario, si intenta esto en noviembre, obtendrá un error. :)
Jordan Reiter
Esto es en realidad mucho más limpio que la solución aceptada. Esto no requiere ninguna importación nueva, solo matemáticas básicas
Simon PA
return datetime.date (año + (new_month / / 12), (new_month% 12) o 12, day)
paytam
9

El paquete Dateutil tiene implementación de dicha funcionalidad. Pero tenga en cuenta que esto será ingenuo , como ya señalaron otros.

zgoda
fuente
dateutil es asombroso. También se puede instalar con easy_install.
Soviut
Excelente. Gracias por sugerir eso. Eso parece ser un enviado de Dios.
ayaz
9

Usando bibliotecas estándar de Python, es decir, sin dateutilu otras, y resolviendo el problema del '31 de febrero':

import datetime
import calendar

def add_months(date, months):
    months_count = date.month + months

    # Calculate the year
    year = date.year + int(months_count / 12)

    # Calculate the month
    month = (months_count % 12)
    if month == 0:
        month = 12

    # Calculate the day
    day = date.day
    last_day_of_month = calendar.monthrange(year, month)[1]
    if day > last_day_of_month:
        day = last_day_of_month

    new_date = datetime.date(year, month, day)
    return new_date

Pruebas:

>>>date = datetime.date(2018, 11, 30)

>>>print(date, add_months(date, 3))
(datetime.date(2018, 11, 30), datetime.date(2019, 2, 28))

>>>print(date, add_months(date, 14))
(datetime.date(2018, 12, 31), datetime.date(2020, 2, 29))
David Ragazzi
fuente
Esto tiene un error: si el mes objetivo es diciembre, devolverá una fecha un año más tarde de lo necesario. Ejemplo: add_months(datetime.date(2018, 11, 30), 1)devoluciones datetime.date(2019, 12, 30)(el año debe ser 2018, no 2019). ¡Entonces, mejor use una biblioteca dedicada y bien probada para esto! Si realmente necesita usar solo módulos de biblioteca estándar, vea mi respuesta a una pregunta similar .
taleinat
5

Tengo una mejor manera de resolver el problema del '31 de febrero':

def add_months(start_date, months):
    import calendar

    year = start_date.year + (months / 12)
    month = start_date.month + (months % 12)
    day = start_date.day

    if month > 12:
        month = month % 12
        year = year + 1

    days_next = calendar.monthrange(year, month)[1]
    if day > days_next:
        day = days_next

    return start_date.replace(year, month, day)

Creo que también funciona con números negativos (para restar meses), pero no lo he probado mucho.

amoyafoss
fuente
1
Esta respuesta tiene el mérito de resolver correctamente el problema utilizando solo bibliotecas Python integradas. Consulte stackoverflow.com/a/4131114/302264 para obtener una respuesta equivalente pero un poco más concisa.
Eduardo Dobay
3

La clase QDate de PyQt4 tiene una función addmonths.

>>>from PyQt4.QtCore import QDate  
>>>dt = QDate(2009,12,31)  
>>>required = dt.addMonths(6) 

>>>required
PyQt4.QtCore.QDate(2010, 6, 30)

>>>required.toPyDate()
datetime.date(2010, 6, 30)
usuario213043
fuente
3

¿Qué tal esto? ¿No estás usando otra biblioteca ( dateutil) o timedelta? Sobre la base de la respuesta de Vartec , hice esto y creo que funciona:

import datetime

today = datetime.date.today()
six_months_from_today = datetime.date(today.year + (today.month + 6)/12, (today.month + 6) % 12, today.day)

Intenté usarlo timedelta, pero porque está contando los días, 365/2o 6*356/12no siempre se traduce en 6 meses, sino en 182 días. p.ej

day = datetime.date(2015, 3, 10)
print day
>>> 2015-03-10

print (day + datetime.timedelta(6*365/12))
>>> 2015-09-08

Creo que generalmente asumimos que 6 meses a partir de un día determinado aterrizarán el mismo día del mes pero 6 meses después (es decir, 2015-03-10-> 2015-09-10, No 2015-09-08)

Espero que esto le sea útil.

Babak K
fuente
1
day + datetime.timedelta(6*365/12)no funcionará siempre, ya que algunos años tienen 365 días y otros tienen 366 días.
3kstc
3

Esto no responde la pregunta específica ( datetimesolo usando ) pero, dado que otros sugirieron el uso de diferentes módulos, aquí hay una solución usando pandas.

import datetime as dt
import pandas as pd

date = dt.date.today() - \
       pd.offsets.DateOffset(months=6)

print(date)

2019-05-04 00:00:00

Que funciona como se esperaba en los años bisiestos

date = dt.datetime(2019,8,29) - \
       pd.offsets.DateOffset(months=6)
print(date)

2019-02-28 00:00:00
rpanai
fuente
2

Modificó AddMonths () para usar en Zope y manejar números de día no válidos:

def AddMonths(d,x):
    days_of_month = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
    newmonth = ((( d.month() - 1) + x ) % 12 ) + 1
    newyear  = d.year() + ((( d.month() - 1) + x ) // 12 ) 
    if d.day() > days_of_month[newmonth-1]:
      newday = days_of_month[newmonth-1]
    else:
      newday = d.day() 
    return DateTime( newyear, newmonth, newday)
Jost
fuente
Esto no parece considerar los años bisiestos (29 días en febrero).
manejar el
2
import time

def add_month(start_time, months):  

        ret = time.strptime(start_time, '%Y-%m-%d')
        t = list(ret)

        t[1] += months

        if t[1] > 12:
            t[0] += 1 + int(months / 12)

            t[1] %= 12

        return int(time.mktime(tuple(t)))
ares
fuente
1
import datetime


'''
Created on 2011-03-09

@author: tonydiep
'''

def add_business_months(start_date, months_to_add):
    """
    Add months in the way business people think of months. 
    Jan 31, 2011 + 1 month = Feb 28, 2011 to business people
    Method: Add the number of months, roll back the date until it becomes a valid date
    """
    # determine year
    years_change = months_to_add / 12

    # determine if there is carryover from adding months
    if (start_date.month + (months_to_add % 12) > 12 ):
        years_change = years_change + 1

    new_year = start_date.year + years_change

    # determine month
    work = months_to_add % 12
    if 0 == work:
        new_month = start_date.month
    else:
        new_month = (start_date.month + (work % 12)) % 12

    if 0 == new_month:
        new_month = 12 

    # determine day of the month
    new_day = start_date.day
    if(new_day in [31, 30, 29, 28]):
        #user means end of the month
        new_day = 31


    new_date = None
    while (None == new_date and 27 < new_day):
        try:
            new_date = start_date.replace(year=new_year, month=new_month, day=new_day)
        except:
            new_day = new_day - 1   #wind down until we get to a valid date

    return new_date


if __name__ == '__main__':
    #tests
    dates = [datetime.date(2011, 1, 31),
             datetime.date(2011, 2, 28),
             datetime.date(2011, 3, 28),
             datetime.date(2011, 4, 28),
             datetime.date(2011, 5, 28),
             datetime.date(2011, 6, 28),
             datetime.date(2011, 7, 28),
             datetime.date(2011, 8, 28),
             datetime.date(2011, 9, 28),
             datetime.date(2011, 10, 28),
             datetime.date(2011, 11, 28),
             datetime.date(2011, 12, 28),
             ]
    months = range(1, 24)
    for start_date in dates:
        for m in months:
            end_date = add_business_months(start_date, m)
            print("%s\t%s\t%s" %(start_date, end_date, m))
Tony Diep
fuente
1

Respuesta de Johannes Wei modificada en el caso 1new_month = 121. Esto funciona perfectamente para mí. Los meses pueden ser positivos o negativos.

def addMonth(d,months=1):
    year, month, day = d.timetuple()[:3]
    new_month = month + months
    return datetime.date(year + ((new_month-1) / 12), (new_month-1) % 12 +1, day)
Xinhui Tang
fuente
2
NO "funciona perfectamente" cuando el día en la fecha de inicio es mayor que la cantidad de días en el mes objetivo. Ejemplo: 2001-01-31 más un mes intenta crear una fecha 2001-02-31.
John Machin
1

Otra solución más: espero que a alguien le guste:

def add_months(d, months):
    return d.replace(year=d.year+months//12).replace(month=(d.month+months)%12)

Esta solución no funciona durante los días 29, 30, 31 para todos los casos, por lo que se necesita una solución más robusta (que ya no es tan agradable :)):

def add_months(d, months):
    for i in range(4):
        day = d.day - i
        try:
            return d.replace(day=day).replace(year=d.year+int(months)//12).replace(month=(d.month+int(months))%12)
        except:
            pass
    raise Exception("should not happen")
Robert Lujo
fuente
1

De esta respuesta , vea parsedatetime . El ejemplo de código sigue. Más detalles: prueba de unidad con muchos ejemplos de conversión en lenguaje natural -> AAAA-MM-DD , y desafíos / errores aparentes de conversión en tiempo de análisis .

#!/usr/bin/env python
# -*- coding: utf-8 -*-
import time, calendar
from datetime import date

# from https://github.com/bear/parsedatetime
import parsedatetime as pdt

def print_todays_date():
    todays_day_of_week = calendar.day_name[date.today().weekday()]
    print "today's date = " + todays_day_of_week + ', ' + \
                              time.strftime('%Y-%m-%d')

def convert_date(natural_language_date):
    cal = pdt.Calendar()
    (struct_time_date, success) = cal.parse(natural_language_date)
    if success:
        formal_date = time.strftime('%Y-%m-%d', struct_time_date)
    else:
        formal_date = '(conversion failed)'
    print '{0:12s} -> {1:10s}'.format(natural_language_date, formal_date)

print_todays_date()
convert_date('6 months')

El código anterior genera lo siguiente desde una máquina MacOSX:

$ ./parsedatetime_simple.py 
today's date = Wednesday, 2015-05-13
6 months     -> 2015-11-13
$ 
Johnny Utahh
fuente
1

Aquí hay un ejemplo que permite al usuario decidir cómo devolver una fecha en la que el día es mayor que la cantidad de días en el mes.

def add_months(date, months, endOfMonthBehaviour='RoundUp'):
    assert endOfMonthBehaviour in ['RoundDown', 'RoundIn', 'RoundOut', 'RoundUp'], \
        'Unknown end of month behaviour'
    year = date.year + (date.month + months - 1) / 12
    month = (date.month + months - 1) % 12 + 1
    day = date.day
    last = monthrange(year, month)[1]
    if day > last:
        if endOfMonthBehaviour == 'RoundDown' or \
            endOfMonthBehaviour == 'RoundOut' and months < 0 or \
            endOfMonthBehaviour == 'RoundIn' and months > 0:
            day = last
        elif endOfMonthBehaviour == 'RoundUp' or \
            endOfMonthBehaviour == 'RoundOut' and months > 0 or \
            endOfMonthBehaviour == 'RoundIn' and months < 0:
            # we don't need to worry about incrementing the year
            # because there will never be a day in December > 31
            month += 1
            day = 1
    return datetime.date(year, month, day)


>>> from calendar import monthrange
>>> import datetime
>>> add_months(datetime.datetime(2016, 1, 31), 1)
datetime.date(2016, 3, 1)
>>> add_months(datetime.datetime(2016, 1, 31), -2)
datetime.date(2015, 12, 1)
>>> add_months(datetime.datetime(2016, 1, 31), -2, 'RoundDown')
datetime.date(2015, 11, 30)
Bruce Jakeway
fuente
1

dado que su variable de fecha y hora se llama fecha:

date=datetime.datetime(year=date.year+int((date.month+6)/12),
                       month=(date.month+6)%13 + (1 if (date.month + 
                       months>12) else 0), day=date.day)
blacknight12321
fuente
1

Función general para obtener la próxima fecha después / antes de x meses.

desde fecha y hora fecha de importación

def after_month (given_date, month):
    aaaa = int (((given_date.year * 12 + given_date.month) + mes) / 12)
    mm = int (((given_date.year * 12 + given_date.month) + mes)% 12)

    si mm == 0:
        aaaa - = 1
        mm = 12
    return given_date.replace (año = aaaa, mes = mm)


if __name__ == "__main__":
    hoy = fecha.today ()
    imprimir (hoy)

    para mm en [-12, -1, 0, 1, 2, 12, 20]:
        next_date = after_month (hoy, mm)
        print (next_date)
Nandlal Yadav
fuente
Esta es claramente la mejor respuesta. Simple y efectivo, sin problemas de redondeo.
jprobichaud
1

Una sugerencia rápida es Arrow

flecha de instalación de pip

>>> import arrow

>>> arrow.now().date()
datetime.date(2019, 6, 28)
>>> arrow.now().shift(months=6).date()
datetime.date(2019, 12, 28)
Diego Magalhães
fuente
0

Use el módulo de fecha y hora de Python para agregar un intervalo de tiempo de seis meses a datetime.today ().

http://docs.python.org/library/datetime.html

Por supuesto, tendrá que resolver el problema planteado por Johannes Weiß: ¿ qué quiere decir con 6 meses?

Devin Jeanpierre
fuente
1
timedelta no admite meses y, por lo tanto, evita las posibles respuestas a la pregunta "¿cuántos días en 6 meses?" El código de Eef establecerá una fecha de revisión, por lo que sugeriría que se considere configurar el timedelta usando días (6 * 30). Si el período representa el acceso de los clientes a un producto / servicio, entonces se puede requerir / preferir una definición comercial.
Carl
0

Esto es lo que se me ocurrió. Mueve la cantidad correcta de meses y años, pero ignora los días (que era lo que necesitaba en mi situación).

import datetime

month_dt = 4
today = datetime.date.today()
y,m = today.year, today.month
m += month_dt-1
year_dt = m//12
new_month = m%12
new_date = datetime.date(y+year_dt, new_month+1, 1)
marshallpenguin
fuente
0

Utilizo esta función para cambiar año y mes, pero mantener el día:

def replace_month_year(date1, year2, month2):
    try:
        date2 = date1.replace(month = month2, year = year2)
    except:
        date2 = datetime.date(year2, month2 + 1, 1) - datetime.timedelta(days=1)
    return date2

Deberías escribir:

new_year = my_date.year + (my_date.month + 6) / 12
new_month = (my_date.month + 6) % 12
new_date = replace_month_year(my_date, new_year, new_month)
gt_rocker
fuente
0

Creo que sería más seguro hacer algo como esto en lugar de agregar días manualmente:

import datetime
today = datetime.date.today()

def addMonths(dt, months = 0):
    new_month = months + dt.month
    year_inc = 0
    if new_month>12:
        year_inc +=1
        new_month -=12
    return dt.replace(month = new_month, year = dt.year+year_inc)

newdate = addMonths(today, 6)
DataGreed
fuente