Como faço para calcular a data de seis meses a partir da data atual usando o módulo Python datetime?

391

Eu estou usando o módulo Python datetime. Eu estou olhando para calcular a data de 6 meses a partir da data atual. Alguém poderia me dar uma ajudinha para fazer isso?

O motivo pelo qual desejo gerar uma data 6 meses a partir da data atual é produzir uma data de revisão . Se o usuário inserir dados no sistema, ele terá uma data de revisão de 6 meses a partir da data em que os dados foram inseridos.

RailsSon
fonte
2
Você terá que ser mais específico: quando são seis meses a partir de 31 de março? E a partir de 30 de agosto?
Kmkaplan 13/02/09
3
Sim, a edição ajuda: significa que você pode aproximar de 6 meses a 183 dias sem nenhum efeito prejudicial. Portanto, adicionar 183 dias hoje fará o truque.
Kmkaplan 13/02/09
15
Os comentários acima me parecem tolos. O conceito de "adição de seis meses" é bastante claro - pegue o componente do mês e adicione 6-o, com suporte para rolar ao longo do ano (e alternar o mês para o mês anterior 1) se passarmos por dezembro. Isso é exatamente o que relativedeltafaz e é de fato o que toda linguagem de programação com suporte para esse tipo de conceito faz.
Kirk Woll
5
@KirkWoll: Tenho certeza de que é bastante claro. Mas ainda é diferente para quem fala. Python: date(2015, 3, 31) + relativedelta(months = 6)datetime.date(2015, 9, 30). Perl: DateTime->new(year=>2000, month=>3, day=>31)->add(months=>6)2000-10-01T00:00:00. Php: date_create('2000-03-31', new DateTimeZone('UTC'))->add(new DateInterval('P6M'))dá 2000-10-01. Escolha o seu veneno.
kmkaplan 10/02
2
... adicionar 182 parece mais pragmático para gerar uma data de revisão : mantém o dia da semana intacto.
Wolf

Respostas:

1047

Eu achei essa solução boa. (Isso usa a extensão python-dateutil )

from datetime import date
from dateutil.relativedelta import relativedelta

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

A vantagem dessa abordagem é que ela resolve problemas com 28, 30, 31 dias etc. Isso se torna muito útil no tratamento de regras e cenários de negócios (por exemplo, geração de faturas 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
fonte
2
a +6 é um indicador que poderia ser -6, a mesma coisa se aplica aos dias e anos como bem :)
securecurve
5
@sliders_alpha Você precisa instalar o pacote python-dateutil (pip instalar python-dateutil)
poiuytrez
18
Esta é a solução correta. Se o OP tivesse solicitado 6 anos em vez de 6 meses, a resposta aprovada falharia miseravelmente. Portanto, é preciso ter em mente que as respostas são mais valiosas quanto mais generalizadas.
Daniel F
3
Observe que a relativedeltafunção também recebe monthcomo argumento, que basicamente substitui / define / corrige o mês na data passada, o que é muito diferente de adicionar mais meses. Apenas um aviso para as pessoas se perguntarem se a função está quebrada porque elas esqueceram os s extras em meses .
shad0w_wa1k3r
11
Estou curioso: alguém sabe por que isso não está incluído por padrão? Timedelta parece embalado datetimepor padrão. Na verdade, presumi que poderia passar "meses" para o timedelta.
dTanMan
51

Bem, isso depende do que você quer dizer com 6 meses a partir da data atual.

  1. Usando meses naturais:

    (day, month, year) = (day, (month + 5) % 12 + 1, year + (month + 5)/12)
  2. Usando a definição de um banqueiro, 6 * 30:

    date += datetime.timedelta(6 * 30)
vartec
fonte
3
Você poderia incluir também a definição de meio ano (183 dias) e a de 26 semanas? Ajuda a tê-los todos em um só lugar.
315/09 S.Lott
11
apenas uma observação rápida: acho que, para o mês, a fórmula seria (mês + 5)% 12 + 1 b / c para junho, sua fórmula fornece 0, enquanto o resultado esperado é 12 ... apesar desse pequeno erro, Na minha opinião, sua resposta é a que melhor responde à pergunta
PierrOz
3
e o mesmo para o ano: deve ser ano + (mês + 5) / 12
PierrOz
7
E se a data for 31 e o mês seis meses depois não puder ter 31 dias (o que ocorre na maioria dos meses com 31 dias)?
AKV
4
Downvote porque a primeira solução (day, month, year) = (day, (month+6)%12, year+(month+6)/12)pode buggy, pois gera datas inválidas tais como (31, 8, 2015)->(31, 2, 2016)
OHW
37

Com o Python 3.x, você pode fazer o seguinte:

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

mas você precisará instalar o módulo python-dateutil :

pip install python-dateutil
Luka Lopusina
fonte
Voto a favor daspip install ...
Nathan
Eu recomendo from dateutil.relativedelta import relativedelta. O uso import *não é explícito.
Sam Morgan
19

Para o cálculo do início do mês para o mês:

from datetime import timedelta
from dateutil.relativedelta import relativedelta

end_date = start_date + relativedelta(months=delta_period) + timedelta(days=-delta_period)
breddi
fonte
18
Esta não é a solução relativedelta mencionada acima nos comentários. Continue rolando para a solução com mais de 600 votos positivos.
Nostalg.io
15

O que você quer dizer com "6 meses"?

2009-02-13 + 6 meses == 2009-08-13? Ou são 13-02-2009 + 6 * 30 dias?

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'

Mais informações sobre mx.DateTime

Johannes Weiss
fonte
14

Então, aqui está um exemplo do dateutil.relativedeltaque eu achei útil para iterar no ano passado, pulando um mês de cada vez para a data atual:

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

Como nas outras respostas, você precisa descobrir o que você realmente quer dizer com "daqui a seis meses". Se você quer dizer "dia do mês de hoje no mês em seis anos no futuro", isso faria:

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

Esta solução funciona corretamente em dezembro, o que a maioria das respostas nesta página não. Você precisa primeiro mudar os meses da base 1 (ou seja, Jan = 1) para a base 0 (ou seja, Jan = 0) antes de usar o módulo (%) ou a divisão inteira (//), caso contrário, novembro (11) mais 1 mês fornece 12 , que ao encontrar o restante (12% 12) fornece 0.

(E não sugira "(mês% 12) + 1" ou outubro + 1 = dezembro!)

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)

No entanto ... Isso não explica problemas como 31 de janeiro + um mês. Então, voltamos ao OP - o que você quer dizer com adicionar um mês? Uma solução é voltar atrás até chegar a um dia válido, já que a maioria das pessoas presumiria o último dia de janeiro, mais um mês, igual ao último dia de fevereiro. Isso também funcionará em números negativos de meses. Prova:

>>> 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)>>> 
user417751
fonte
3
Corrige o problema "31 de janeiro + um mês": days_in_month = calendar.monthrange (newyear, newmonth) [1]; newday = min (d.day, days_in_month); (bate o dia se for muito grande, por exemplo, 31 de fevereiro a 28 de fevereiro / 29)
Curtis Yallop
Isso funcionou para mim apenas convertendo o ano novo em um tipo de dados inteiro def AddMonths (d, x): newmonth = (((d.month - 1) + x)% 12) + 1 newyear = d.year + int (( (d.month - 1) + x) / 12) retornar datetime.date (newyear, newmonth, d.day)
Manmeet Singh
12

Eu sei que isso foi por 6 meses, no entanto, a resposta mostra no google para "adicionar meses em python" se você estiver adicionando um mês:

import calendar

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

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

isso contaria os dias do mês atual e os adicionaria à data atual, o uso de 365/12 e 1/12 de um ano pode causar problemas por meses curtos / longos se você estiver repetindo a data.

Mike Davies
fonte
11

Não existe uma maneira direta de fazer isso com a data e hora do Python.

Confira o tipo relativedelta em python-dateutil . Permite especificar um delta de tempo em meses.

Akbar ibrahim
fonte
10

Basta usar o método de cronograma para extrair os meses, adicionar seus meses e criar um novo objeto de data. Se já existe um método para isso, eu não o conheço.

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)

A API é um pouco desajeitada, mas funciona como um exemplo. Obviamente, também não funcionará em casos extremos como 2008-01-31 + 1 mês. :)

pi.
fonte
3
Erro no seu código: new_month % 12deve ser (new_month % 12) or 12. Caso contrário, se você tentar isso em novembro, receberá um erro. :)
Jordan Reiter
Isso é realmente muito mais limpo que a solução aceita. Isto não requer qualquer nova importação, matemática apenas básicas
Simon PA
return datetime.date (ano + (new_month / / 12), (new_month% 12) ou 12, dia)
paytam
9

O pacote Dateutil possui implementação dessa funcionalidade. Mas esteja ciente de que isso será ingênuo , como outros já apontaram.

zgoda
fonte
dateutil é incrível. Também pode ser instalado com o easy_install.
Soviut
Excelente. Obrigado por sugerir isso. Isso parece ser enviado por Deus.
Ayaz
9

Usando bibliotecas padrão do Python, ou seja, sem dateutilou outras, e resolvendo o problema '31 de fevereiro':

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

Teste:

>>>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
fonte
Isso tem um erro: se o mês alvo for dezembro, ele retornará uma data um ano depois do necessário. Exemplo: add_months(datetime.date(2018, 11, 30), 1)retornos datetime.date(2019, 12, 30)(o ano deve ser 2018, não 2019). Portanto, é melhor usar uma biblioteca dedicada e bem testada para isso! Se você realmente precisa usar apenas módulos de biblioteca padrão, veja minha resposta para uma pergunta semelhante .
taleinat
5

Eu tenho uma maneira melhor de resolver o problema '31 de fevereiro':

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)

Eu acho que também funciona com números negativos (para subtrair meses), mas não testei muito isso.

amoyafoss
fonte
11
Esta resposta tem o mérito de resolver corretamente o problema usando apenas bibliotecas Python internas. Verifique stackoverflow.com/a/4131114/302264 para obter uma resposta equivalente, mas um pouco mais concisa.
Eduardo Dobay
3

A classe QDate do PyQt4 possui uma função 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)
user213043
fonte
3

Que tal agora? Não está usando outra biblioteca ( dateutil) ou timedelta? com base na resposta da vartec , fiz isso e acredito 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)

Eu tentei usar timedelta, mas porque conta os dias 365/2ou 6*356/12nem sempre se traduz em 6 meses, mas sim em 182 dias. por exemplo

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

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

Acredito que geralmente assumimos que 6 meses a partir de um determinado dia chegarão no mesmo dia do mês, mas 6 meses depois (ie 2015-03-10-> 2015-09-10, Não 2015-09-08)

Eu espero que você ache isto útil.

Babak K
fonte
11
day + datetime.timedelta(6*365/12)nem sempre funcionará, pois alguns anos têm 365 dias e outros 366.
3kstc
3

Isso não responde à pergunta específica (usando datetimeapenas), mas, como outros sugeriram o uso de módulos diferentes, aqui há uma solução 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

O que funciona como esperado em anos bissextos

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

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

Modificados os AddMonths () para uso no Zope e manipulação de números de dia invá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
fonte
Isso não parece considerar anos bissextos (29 dias em fevereiro).
manipula
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
fonte
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
fonte
1

Resposta de Johannes Wei modificada no caso 1new_month = 121. Isso funciona perfeitamente para mim. Os meses podem ser positivos ou 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
fonte
2
"NÃO funciona perfeitamente" quando o dia na data de início é maior que o número de dias no mês de destino. Exemplo: 2001-01-31 mais um mês tenta criar uma data 2001-02-31.
John Machin
1

Mais uma solução - espero que alguém goste:

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

Esta solução não funciona nos dias 29,30,31 para todos os casos, por isso é necessária uma solução mais robusta (que não é mais tão agradável :)):

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
fonte
1

A partir desta resposta , consulte ParseDateTime . Exemplo de código a seguir. Mais detalhes: teste de unidade com muitos exemplos de conversão de idioma natural -> AAAA-MM-DD e desafios / bugs aparentes de conversão em tempo analisado .

#!/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')

O código acima gera o seguinte em uma máquina MacOSX:

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

Aqui está um exemplo que permite ao usuário decidir como retornar uma data em que o dia é maior que o número de dias no mês.

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
fonte
1

dado que sua variável datetime é chamada date:

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
fonte
1

Função geral para obter a próxima data após / antes de x meses.

a partir da data de importação da data e hora

def after_month (data_data, mês):
    aaaa = int (((data_data.ano * 12 + data_data.month) + mês) / 12)
    mm = int (((dado_data.ano * 12 + dado_data.month) + mês)% 12)

    se mm == 0:
        aaaa - = 1
        mm = 12
    retornar dado_data.replace (ano = aaaa, mês = mm)


se __name__ == "__main__":
    today = date.today ()
    print (hoje)

    para mm em [-12, -1, 0, 1, 2, 12, 20]:
        next_date = after_month (hoje, mm)
        print (próxima_data)
Nandlal Yadav
fonte
Esta é claramente a melhor resposta. Simples e eficaz, sem problemas de arredondamento.
Jprobichaud #
1

Uma sugestão rápida é Arrow

seta de instalação do 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
fonte
0

Use o módulo datetime python para adicionar um intervalo de tempo de seis meses a datetime.today ().

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

Obviamente, você terá que resolver a questão levantada por Johannes Weiß - o que você quer dizer com 6 meses?

Devin Jeanpierre
fonte
11
O timedelta não suporta meses e, portanto, evita as respostas possíveis para a pergunta "quantos dias em seis meses?" O código do Eef definirá uma data de revisão, então eu sugeriria que alguém pudesse considerar definir o cronograma usando dias (6 * 30). Se o período representar o acesso dos clientes a um produto / serviço, uma definição de negócios poderá ser necessária / preferida.
Carl Carl
0

Isto é o que eu vim com. Ele move o número correto de meses e anos, mas ignora os dias (que era o que eu precisava na minha situação).

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
fonte
0

Eu uso essa função para alterar ano e mês, mas manter o dia:

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

Você deve escrever:

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
fonte
0

Eu acho que seria mais seguro fazer algo assim em vez de adicionar dias 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
fonte