Как рассчитать дату через шесть месяцев от текущей даты, используя модуль Python datetime?

391

Я использую модуль Python datetime. Я рассчитываю рассчитать дату 6 месяцев с текущей даты. Может ли кто-нибудь помочь мне с этим?

Причина, по которой я хочу создать дату через 6 месяцев после текущей даты, заключается в том, чтобы создать дату проверки . Если пользователь вводит данные в систему, у него будет дата проверки 6 месяцев с даты ввода данных.

RailsSon
источник
2
Вам нужно быть более конкретным: когда наступит шесть месяцев с 31 марта? А с 30 августа?
kmkaplan
3
Да, редактирование помогает: это означает, что вы можете приблизить от 6 месяцев до 183 дней без вреда для здоровья. Таким образом, добавление 183 дней к сегодняшнему дню поможет.
kmkaplan
15
Приведенные выше комментарии кажутся мне глупыми. Концепция «добавления шести месяцев» совершенно ясна - возьмите компонент «месяц» и добавьте 6к нему, с поддержкой 1перехода на следующий год (и циклический переход к месяцу назад ), если мы пойдем после декабря. Это именно то, что relativedeltaделает и на самом деле делает каждый язык программирования с поддержкой такого рода концепций.
Кирк Уолл
5
@KirkWoll: я уверен, что это совершенно ясно. Но все равно отличается для тех, кто говорит. Питон: 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'))2000-10-01. Выбрать свой яд.
kmkaplan
2
... добавление 182 кажется более прагматичным для создания даты обзора : оно сохраняет день недели без изменений.
Wolf

Ответы:

1047

Я нашел это решение, чтобы быть хорошим. (Это использует расширение python-dateutil )

from datetime import date
from dateutil.relativedelta import relativedelta

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

Преимущество этого подхода заключается в том, что он решает проблемы с 28, 30, 31 днем ​​и т. Д. Это становится очень полезным при обработке бизнес-правил и сценариев (например, генерация счетов и т. Д.)

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

$ date(2010,12,31)+relativedelta(months=+2)
  datetime.date(2011, 2, 28)
Мээндра
источник
2
+6 - это показатель того, что это может быть -6, то же самое относится и к дням и годам :)
securecurve
5
@sliders_alpha Вам необходимо установить пакет python-dateutil (pip install python-dateutil)
poiuytrez
18
Это правильное решение. Если бы ОП попросил 6 лет вместо 6 месяцев, то утвержденный ответ потерпел бы неудачу. Поэтому следует иметь в виду, что ответы тем ценнее, чем более обобщенными они являются.
Даниэль Ф
3
Пожалуйста, обратите внимание, что relativedeltaфункция также принимает в monthкачестве аргумента, который в основном заменяет / устанавливает / исправляет месяц в переданной дате, что сильно отличается от добавления большего количества месяцев. Просто предупреждение для людей, задающихся вопросом, нарушена ли функция, потому что они забыли дополнительные s в месяцах .
shad0w_wa1k3r
1
Мне любопытно: кто-нибудь знает, почему это не включено по умолчанию? Timedelta, кажется, упакована с datetimeпо умолчанию. Я действительно предполагал, что смогу провести «месяцы» в timedelta.
ДанМан
51

Ну, это зависит от того, что вы подразумеваете под 6 месяцами от текущей даты.

  1. Используя естественные месяцы:

    (day, month, year) = (day, (month + 5) % 12 + 1, year + (month + 5)/12)
  2. Используя определение банкира, 6 * 30:

    date += datetime.timedelta(6 * 30)
Vartec
источник
3
Не могли бы вы добавить определение полугодия (183 дня) плюс определение 26 недель? Это помогает иметь их всех в одном месте.
S.Lott
11
просто быстрое замечание: я думаю, для месяца формула будет вместо (месяц + 5)% 12 + 1 б / с для июня, ваша формула дает 0, тогда как ожидаемый результат равен 12 ... несмотря на эту небольшую ошибку, я думаю, что ваш ответ - тот, который лучше всего отвечает на вопрос
PierrOz
3
и то же самое для года: это должен быть год + (месяц + 5) / 12
PierrOz
7
Что если дата 31, а месяц через шесть месяцев не может иметь 31 день (что имеет место в большинстве месяцев с 31 днем)?
А
4
Downvote , потому что первое решение (day, month, year) = (day, (month+6)%12, year+(month+6)/12)может глючит, так как она создает недопустимые даты , такие как (31, 8, 2015)->(31, 2, 2016)
OHW
37

С Python 3.x вы можете сделать это так:

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

но вам нужно будет установить модуль python-dateutil :

pip install python-dateutil
Лука Лопусина
источник
Проголосовал заpip install ...
Натан
Я бы порекомендовал from dateutil.relativedelta import relativedelta. Использование import *не является явным.
Сэм Морган
19

Для начала расчета месяца к месяцу:

from datetime import timedelta
from dateutil.relativedelta import relativedelta

end_date = start_date + relativedelta(months=delta_period) + timedelta(days=-delta_period)
breddi
источник
18
Это не относительное решение, упомянутое выше в комментариях. Продолжайте прокручивать для решения с 600+ голосов.
Nostalg.io
15

Что вы подразумеваете под "6 месяцев"?

2009-02-13 + 6 месяцев == 2009-08-13? Или это 2009-02-13 + 6 * 30 дней?

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'

Больше информации о mx.DateTime

Йоханнес Вайс
источник
14

Итак, вот пример, dateutil.relativedeltaкоторый я нашел полезным для итерации в течение прошлого года, пропуская месяц каждый раз до текущей даты:

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

Как и в случае с другими ответами, вы должны выяснить, что вы на самом деле подразумеваете под «через 6 месяцев». Если вы имеете в виду «сегодняшний день месяца в месяце шесть лет в будущем», то это будет делать:

datetime.datetime.now() + relativedelta(months=6)
dannyman
источник
14

Это решение работает правильно для декабря, что большинство ответов на этой странице нет. Прежде чем использовать модуль (%) или целочисленное деление (//), необходимо сначала сдвинуть месяцы с основания 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  = int(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)>>> 
user417751
источник
3
Исправляет проблему «31 января + один месяц»: days_in_month = calendar.monthrange (newyear, newmonth) [1]; newday = min (d.day, days_in_month); (поднимает день, если он слишком большой, например, с 31 февраля по 28/29 февраля)
Кертис Яллоп
Это сработало для меня только путем преобразования нового года в целочисленный тип данных 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)
Манмит Сингх,
12

Я знаю, что это было в течение 6 месяцев, однако ответ показывает в Google для «добавления месяцев в Python», если вы добавляете один месяц:

import calendar

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

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

это будет считать дни в текущем месяце и добавлять их к текущей дате, использование 365/12 может привести к тому, что 1/12 года может вызвать проблемы на короткие / длинные месяцы, если вы выполняете итерацию по дате.

Майк Дэвис
источник
11

Нет прямого способа сделать это с датой Python.

Проверьте тип относительной дельты в python-dateutil . Позволяет указать дельту времени в месяцах.

Акбар Ибрагим
источник
10

Просто используйте метод timetuple, чтобы извлечь месяцы, добавить свои месяцы и построить новый объект date. Если для этого уже существует метод, я не знаю его.

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)

API немного неуклюж, но работает как пример. Также явно не будет работать на угловых делах, таких как 2008-01-31 + 1 месяц. :)

Пи.
источник
3
Ошибка в вашем коде: new_month % 12должно быть (new_month % 12) or 12. В противном случае, если вы попробуете это в ноябре, вы получите ошибку. :)
Джордан Рейтер
Это на самом деле намного чище, чем принятое решение. Это не требует какого-либо нового импорта, только базовая математика
Simon PA
return datetime.date (year + (new_month / / 12), (new_month% 12) или 12, day)
paytam
9

В пакете Dateutil реализована такая функциональность. Но имейте в виду, что это будет наивно , как уже указывали другие.

Zgoda
источник
dateutil - это круто Его также можно установить с помощью easy_install.
Совют
Отлично. Спасибо, что предложили это. Кажется, это послан Богом.
Аяз
9

Использование стандартных библиотек Python, т.е. без dateutilили других, и решение проблемы «31 февраля»:

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

Тестирование:

>>>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))
Давид Рагацци
источник
В этом есть ошибка: если целевой месяц декабрь, он вернет дату на год позже, чем необходимо. Пример: add_months(datetime.date(2018, 11, 30), 1)возврат datetime.date(2019, 12, 30)(год должен быть 2018, а не 2019). Так что для этого лучше использовать выделенную, хорошо протестированную библиотеку! Если вам действительно нужно использовать только стандартные библиотечные модули, см. Мой ответ на аналогичный вопрос .
taleinat
5

У меня есть лучший способ решить проблему «31 февраля»:

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)

Я думаю, что это также работает с отрицательными числами (чтобы вычесть месяцы), но я не очень проверял это.

amoyafoss
источник
1
Этот ответ имеет смысл для правильного решения проблемы с использованием только встроенных библиотек Python. Проверьте stackoverflow.com/a/4131114/302264 для эквивалентного, но немного более краткого ответа.
Эдуардо Добай
3

Класс QDate PyQt4 имеет функцию 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
источник
3

Как насчет этого? Не используете другую библиотеку ( dateutil) или timedelta? основываясь на ответе vartec , я сделал это и считаю, что это работает:

import datetime

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

Я пытался использовать timedelta, но потому, что он считает дни 365/2или 6*356/12не всегда переводит на 6 месяцев, а точнее на 182 дня. например

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

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

Я полагаю, что мы обычно предполагаем, что 6 месяцев с определенного дня приземляются в тот же день месяца, но через 6 месяцев (то есть 2015-03-10-> 2015-09-10, Нет 2015-09-08)

Я надеюсь, что вы найдете это полезным.

Бабак К
источник
1
day + datetime.timedelta(6*365/12)не будет работать всегда, поскольку у некоторых лет есть 365 дней, а у других 366 дней.
3
3

Это не отвечает на конкретный вопрос (используется datetimeтолько), но, учитывая, что другие предложили использовать различные модули, здесь есть решение с использованием 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

Который работает как положено в високосные годы

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

2019-02-28 00:00:00
rpanai
источник
2

Изменен AddMonths () для использования в Zope и обработки недопустимых номеров дней:

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
источник
Это не похоже на високосные годы (29 дней в фев).
обрабатывать
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)))
аров
источник
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))
Тони Дип
источник
1

Модифицированный ответ Йоханнеса Вея в случае 1new_month = 121. Это прекрасно работает для меня. Месяцы могут быть положительными или отрицательными.

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
источник
2
Он не «работает идеально», когда день в начальной дате больше, чем количество дней в целевом месяце. Пример: 2001-01-31 плюс один месяц пытается создать дату 2001-02-31.
Джон Мачин
1

Еще одно решение - надеюсь, кому-то понравится:

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

Это решение не работает в течение 29, 30, 31 дней для всех случаев, поэтому требуется более надежное решение (что уже не так приятно :)):

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")
Роберт Лужо
источник
1

Из этого ответа смотрите parsedatetime . Пример кода приведен ниже. Более подробная информация: модульное тестирование с множеством примеров преобразования на естественном языке -> ГГГГ-ММ-ДД и очевидные проблемы / ошибки преобразования во время анализа .

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

Приведенный выше код генерирует следующее на компьютере MacOSX:

$ ./parsedatetime_simple.py 
today's date = Wednesday, 2015-05-13
6 months     -> 2015-11-13
$ 
Джонни Юта
источник
1

Вот пример, который позволяет пользователю решить, как вернуть дату, где день больше, чем количество дней в месяце.

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)
Брюс Джейквей
источник
1

учитывая, что ваша переменная datetime называется 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
источник
1

Общая функция, чтобы получить следующую дату после / до х месяцев.

с даты / даты импорта

def after_month (данное_дата, месяц):
    гггг = int (((дано_дата.год * 12 + дано_дата.месяц) + месяц) / 12)
    мм = int (((Given_date.year * 12 + Given_date.month) + месяц)% 12)

    если мм == 0:
        гггг - = 1
        мм = 12
    возвращать данное_данные.replace (год = гггг, месяц = ​​мм)


if __name__ == "__main__":
    сегодня = дата.день ()
    печать (сегодня)

    для мм в [-12, -1, 0, 1, 2, 12, 20]:
        next_date = after_month (сегодня, мм)
        печать (next_date)
Нандлал Ядав
источник
Это явно лучший ответ. Просто и эффективно, без вопросов округления.
jprobichaud
1

Быстрое предложение - Стрелка

стрелка установки пипа

>>> import arrow

>>> arrow.now().date()
datetime.date(2019, 6, 28)
>>> arrow.now().shift(months=6).date()
datetime.date(2019, 12, 28)
Диего Магальес
источник
0

Используйте модуль python datetime, чтобы добавить timedelta из шести месяцев в datetime.today ().

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

Вы, конечно , придется решать вопрос , поднятый Johannes Weiß-- что делать вы имеете в виду на 6 месяцев?

Девин Жанпьер
источник
1
timedelta не поддерживает месяцы и поэтому обходит возможные ответы на вопрос "сколько дней в 6 месяцах?" Код Eef установит дату пересмотра, поэтому я бы посоветовал рассмотреть возможность установки временной шкалы с использованием дней (6 * 30). Если период представляет собой доступ клиентов к продукту / услуге, тогда может потребоваться / предпочтительным определение бизнеса.
Карл
0

Это то, что я придумал. Он перемещает правильное количество месяцев и лет, но игнорирует дни (это было то, что мне было нужно в моей ситуации).

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
источник
0

Я использую эту функцию, чтобы изменить год и месяц, но сохранить день:

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

Вы должны написать:

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
источник
0

Я думаю, что было бы безопаснее сделать что-то подобное, а не добавлять дни вручную:

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
источник