Это решение работает правильно для декабря, что большинство ответов на этой странице нет.
Прежде чем использовать модуль (%) или целочисленное деление (//), необходимо сначала сдвинуть месяцы с основания 1 (т.е. января = 1) на основание 0 (т.е. января = 0), в противном случае ноябрь (11) плюс 1 месяц дает вам 12 , который при нахождении остатка (12% 12) дает 0.
(И не предлагайте "(месяц% 12) + 1" или октябрь + 1 = декабрь!)
def AddMonths(d,x):
newmonth = ((( d.month - 1) + x ) % 12 ) + 1
newyear = d.year + ((( d.month - 1) + x ) / 12 )
return datetime.date( newyear, newmonth, d.day)
Однако ... Это не объясняет проблему, такую как 31 января + один месяц. Итак, мы возвращаемся к ОП - что вы имеете в виду, добавляя месяц? Единственное, что нужно сделать, это вернуться назад, пока вы не доберетесь до действительного дня, учитывая, что большинство людей предполагает, что последний день января плюс один месяц равен последнему дню февраля.
Это будет работать и на отрицательных числах месяцев.
Доказательство:
>>> 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)>>>