# How do I calculate the date six months from the current date using the datetime Python module?

## The Question :

440 people think this question is useful

I am using the datetime Python module. I am looking to calculate the date 6 months from the current date. Could someone give me a little help doing this?

The reason I want to generate a date 6 months from the current date is to produce a review date. If the user enters data into the system it will have a review date of 6 months from the date they entered the data.

• You will have to be more specific : when is six months from march 31th? And from august 30th?
• Yes the edit helps: it means you can aproximate 6 months to 183 days with no ill effect. So adding 183 days to today will do the trick.
• The above comments strike me as silly. The concept of “adding six months” is quite clear — take the month component and add 6 to it, with support for rolling over the year (and cycling the month back to 1) if we go past December. This happens to be exactly what relativedelta does and is in fact what every programming language with support for this sort of concept does.
• @KirkWoll: I am sure it is quite clear. But still different for whoever speaks. Python: date(2015, 3, 31) + relativedelta(months = 6) gives datetime.date(2015, 9, 30). Perl: DateTime->new(year=>2000, month=>3, day=>31)->add(months=>6) gives 2000-10-01T00:00:00. Php: date_create('2000-03-31', new DateTimeZone('UTC'))->add(new DateInterval('P6M')) gives 2000-10-01. Pick your poison.
• … adding 182 seems more pragmatic for generating a review date: it keeps the day of the week intact.

1119 people think this answer is useful

I found this solution to be good. (This uses the python-dateutil extension)

from datetime import date
from dateutil.relativedelta import relativedelta

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



The advantage of this approach is that it takes care of issues with 28, 30, 31 days etc. This becomes very useful in handling business rules and scenarios (say invoice generation 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)



57 people think this answer is useful

Well, that depends what you mean by 6 months from the current date.

1. Using natural months:

(day, month, year) = (day, (month + 5) % 12 + 1, year + (month + 5)/12)


2. Using a banker’s definition, 6*30:

date += datetime.timedelta(6 * 30)



41 people think this answer is useful

With Python 3.x you can do it like this:

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



but you will need to install python-dateutil module:

pip install python-dateutil



19 people think this answer is useful

For beginning of month to month calculation:

from datetime import timedelta
from dateutil.relativedelta import relativedelta

end_date = start_date + relativedelta(months=delta_period) + timedelta(days=-delta_period)



17 people think this answer is useful

What do you mean by “6 months”?

Is 2009-02-13 + 6 months == 2009-08-13? Or is it 2009-02-13 + 6*30 days?

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'



16 people think this answer is useful

This solution works correctly for December, which most of the answers on this page do not. You need to first shift the months from base 1 (ie Jan = 1) to base 0 (ie Jan = 0) before using modulus ( % ) or integer division ( // ), otherwise November (11) plus 1 month gives you 12, which when finding the remainder ( 12 % 12 ) gives 0.

(And dont suggest “(month % 12) + 1” or Oct + 1 = december!)

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)



However … This doesnt account for problem like Jan 31 + one month. So we go back to the OP – what do you mean by adding a month? One solution is to backtrack until you get to a valid day, given that most people would presume the last day of jan, plus one month, equals the last day of Feb. This will work on negative numbers of months too. Proof:

>>> import datetime
datetime.date(2010, 9, 25)
datetime.date(2010, 12, 25)
datetime.date(2011, 1, 25)
datetime.date(2011, 9, 25)
datetime.date(2012, 8, 25)
datetime.date(2010, 7, 25)
datetime.date(2010, 8, 25)
datetime.date(2009, 8, 25)
datetime.date(2009, 12, 25)
datetime.date(2010, 1, 25)>>>



14 people think this answer is useful

So, here is an example of the dateutil.relativedelta which I found useful for iterating through the past year, skipping a month each time to the present date:

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



As with the other answers, you have to figure out what you actually mean by “6 months from now.” If you mean “today’s day of the month in the month six years in the future” then this would do:

datetime.datetime.now() + relativedelta(months=6)



12 people think this answer is useful

I know this was for 6 months, however the answer shows in google for “adding months in python” if you are adding one month:

import calendar

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

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



this would count the days in the current month and add them to the current date, using 365/12 would ad 1/12 of a year can causes issues for short / long months if your iterating over the date.

11 people think this answer is useful

There’s no direct way to do it with Python’s datetime.

Check out the relativedelta type at python-dateutil. It allows you to specify a time delta in months.

11 people think this answer is useful

Just use the timetuple method to extract the months, add your months and build a new dateobject. If there is a already existing method for this I do not know it.

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)



The API is a bit clumsy, but works as an example. Will also obviously not work on corner-cases like 2008-01-31 + 1 month. 🙂

10 people think this answer is useful

Using Python standard libraries, i.e. without dateutil or others, and solving the ‘February 31st’ problem:

import datetime
import calendar

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)
if day > last_day_of_month:
day = last_day_of_month

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



Testing:

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

(datetime.date(2018, 11, 30), datetime.date(2019, 2, 28))

(datetime.date(2018, 12, 31), datetime.date(2020, 2, 29))



9 people think this answer is useful

Dateutil package has implementation of such functionality. But be aware, that this will be naive, as others pointed already.

8 people think this answer is useful

This doesn’t answer the specific question (using datetime only) but, given that others suggested the use of different modules, here there is a solution using 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



Which works as expected in leap years

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

2019-02-28 00:00:00



5 people think this answer is useful

I have a better way to solve the ‘February 31st’ problem:

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)
if day > days_next:
day = days_next

return start_date.replace(year, month, day)



I think that it also works with negative numbers (to subtract months), but I haven’t tested this very much.

4 people think this answer is useful

The QDate class of PyQt4 has an addmonths function.

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

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

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



3 people think this answer is useful

How about this? Not using another library (dateutil) or timedelta? building on vartec‘s answer I did this and I believe it works:

import datetime

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



I tried using timedelta, but because it is counting the days, 365/2 or 6*356/12 does not always translate to 6 months, but rather 182 days. e.g.

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

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



I believe that we usually assume that 6 month’s from a certain day will land on the same day of the month but 6 months later (i.e. 2015-03-10 –> 2015-09-10, Not 2015-09-08)

I hope you find this helpful.

2 people think this answer is useful

Modified the AddMonths() for use in Zope and handling invalid day numbers:

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)



2 people think this answer is useful
import time

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

t += months

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

t %= 12

return int(time.mktime(tuple(t)))



2 people think this answer is useful

Modified Johannes Wei’s answer in the case 1new_month = 121. This works perfectly for me. The months could be positive or negative.

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)



2 people think this answer is useful

A quick suggestion is Arrow

pip install arrow

>>> import arrow

>>> arrow.now().date()
datetime.date(2019, 6, 28)
>>> arrow.now().shift(months=6).date()
datetime.date(2019, 12, 28)



1 people think this answer is useful
import datetime

'''
Created on 2011-03-09

@author: tonydiep
'''

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

# 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
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:
print("%s\t%s\t%s" %(start_date, end_date, m))



1 people think this answer is useful

Yet another solution – hope someone will like it:

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



This solution doesn’t work for days 29,30,31 for all cases, so more robust solution is needed (which is not so nice anymore 🙂 ):

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 people think this answer is useful

From this answer, see parsedatetime. Code example follows. More details: unit test with many natural-language -> YYYY-MM-DD conversion examples, and apparent parsedatetime conversion challenges/bugs.

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



The above code generates the following from a MacOSX machine:

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



1 people think this answer is useful

Here’s a example which allows the user to decide how to return a date where the day is greater than the number of days in the month.

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)
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
datetime.date(2016, 3, 1)
datetime.date(2015, 12, 1)
>>> add_months(datetime.datetime(2016, 1, 31), -2, 'RoundDown')
datetime.date(2015, 11, 30)



1 people think this answer is useful

given that your datetime variable is called 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)



1 people think this answer is useful

General function to get next date after/before x months.

from datetime import date

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

if mm == 0:
yyyy -= 1
mm = 12
return given_date.replace(year=yyyy, month=mm)

if __name__ == "__main__":
today = date.today()
print(today)

for mm in [-12, -1, 0, 1, 2, 12, 20 ]:
next_date = after_month(today, mm)
print(next_date)


1 people think this answer is useful

The “python-dateutil” (external extension) is a good solution, but you can do it with build-in Python modules (datetime and datetime)

I made a short and simple code, to solve it (dealing with year, month and day)

(running: Python 3.8.2)

from datetime import datetime
from calendar import monthrange

# Time to increase (in months)
inc = 12

# Returns mod of the division for 12 (months)
month = ((datetime.now().month + inc) % 12) or 1

# Increase the division by 12 (months), if necessary (+ 12 months increase)
year = datetime.now().year + int((month + inc) / 12)

# (IF YOU DON'T NEED DAYS,CAN REMOVE THE BELOW CODE)
# Returns the same day in new month, or the maximum day of new month
day = min(datetime.now().day,monthrange(year, month))

print("Year: {}, Month: {}, Day: {}".format(year, month, day))



0 people think this answer is useful

This is what I came up with. It moves the correct number of months and years but ignores days (which was what I needed in my situation).

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)



0 people think this answer is useful

I use this function to change year and month but keep day:

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



You should write:

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)



0 people think this answer is useful

I think it would be safer to do something like this instead of manually adding days:

import datetime
today = datetime.date.today()