How do I calculate the date six months from the current date using the datetime Python module?
PythonDatetimePython Problem Overview
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.
Python Solutions
Solution 1 - Python
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)
Solution 2 - Python
Well, that depends what you mean by 6 months from the current date.
-
Using natural months:
inc = 6 month = (month + inc - 1) % 12 + 1 year = year + (month + inc - 1) // 12
-
Using a banker's definition, 6*30:
date += datetime.timedelta(6 * 30)
Solution 3 - Python
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
Solution 4 - Python
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)
Solution 5 - Python
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)
Solution 6 - Python
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
>>> 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)>>>
Solution 7 - Python
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'
More info about mx.DateTime
Solution 8 - Python
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.
Solution 9 - Python
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
Solution 10 - Python
Python can use datautil package for that, Please see the example below
It's not Just limited to that, you can pass combination of days, Months and Years at the same time also.
import datetime
from dateutil.relativedelta import relativedelta
# subtract months
proc_dt = datetime.date(2021,8,31)
proc_dt_minus_3_months = proc_dt + relativedelta(months=-3)
print(proc_dt_minus_3_months)
# add months
proc_dt = datetime.date(2021,8,31)
proc_dt_plus_3_months = proc_dt + relativedelta(months=+3)
print(proc_dt_plus_3_months)
# subtract days:
proc_dt = datetime.date(2021,8,31)
proc_dt_minus_3_days = proc_dt + relativedelta(days=-3)
print(proc_dt_minus_3_days)
# add days days:
proc_dt = datetime.date(2021,8,31)
proc_dt_plus_3_days = proc_dt + relativedelta(days=+3)
print(proc_dt_plus_3_days)
# subtract years:
proc_dt = datetime.date(2021,8,31)
proc_dt_minus_3_years = proc_dt + relativedelta(years=-3)
print(proc_dt_minus_3_years)
# add years:
proc_dt = datetime.date(2021,8,31)
proc_dt_plus_3_years = proc_dt + relativedelta(years=+3)
print(proc_dt_plus_3_years)
Results:
2021-05-31
2021-11-30
2021-08-28
2021-09-03
2018-08-31
2024-08-31
Solution 11 - Python
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. :)
Solution 12 - Python
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)[1])
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.
Solution 13 - Python
Using Python standard libraries, i.e. without dateutil
or others, and solving the 'February 31st' problem:
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
Testing:
>>>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))
Solution 14 - Python
Dateutil package has implementation of such functionality. But be aware, that this will be naive, as others pointed already.
Solution 15 - Python
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)[1]
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.
Solution 16 - Python
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.
Solution 17 - Python
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)
Solution 18 - Python
The QDate class of PyQt4 has an addmonths function.
>>>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)
Solution 19 - Python
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)
Solution 20 - Python
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)
Solution 21 - Python
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)))
Solution 22 - Python
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))
Solution 23 - Python
Rework of an earlier answer by user417751. Maybe not so pythonic way, but it takes care of different month lengths and leap years. In this case 31 January 2012 + 1 month = 29 February 2012.
import datetime
import calendar
def add_mths(d, x):
newday = d.day
newmonth = (((d.month - 1) + x) % 12) + 1
newyear = d.year + (((d.month - 1) + x) // 12)
if newday > calendar.mdays[newmonth]:
newday = calendar.mdays[newmonth]
if newyear % 4 == 0 and newmonth == 2:
newday += 1
return datetime.date(newyear, newmonth, newday)
Solution 24 - Python
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")
Solution 25 - Python
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
$
Solution 26 - Python
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)[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)
Solution 27 - Python
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)
Solution 28 - Python
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)
Solution 29 - Python
Im chiming in late, but
check out Ken Reitz Maya module,
https://github.com/kennethreitz/maya
something like this may help you, just change hours=1 to days=1 or years=1
>>> from maya import MayaInterval
# Create an event that is one hour long, starting now.
>>> event_start = maya.now()
>>> event_end = event_start.add(hours=1)
>>> event = MayaInterval(start=event_start, end=event_end)
Solution 30 - Python
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)[1])
print("Year: {}, Month: {}, Day: {}".format(year, month, day))
Solution 31 - Python
I often need last day of month to remain last day of month. To solve that I add one day before calculation and then subtract it again before return.
from datetime import date, timedelta
# it's a lot faster with a constant day
DAY = timedelta(1)
def add_month(a_date, months):
"Add months to date and retain last day in month."
next_day = a_date + DAY
# calculate new year and month
m_sum = next_day.month + months - 1
y = next_day.year + m_sum // 12
m = m_sum % 12 + 1
try:
return date(y, m, next_day.day) - DAY
except ValueError:
# on fail return last day in month
# can't fail on december so I don't bother changing the year
return date(y, m + 1, 1) - DAY
Solution 32 - Python
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)
Solution 33 - Python
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)
Solution 34 - Python
I think it would be safer to do something like this instead of manually adding days:
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)
Solution 35 - Python
I solved this problem like this:
import calendar
from datetime import datetime
moths2add = 6
now = datetime.now()
current_year = now.year
current_month = now.month
#count days in months you want to add using calendar module
days = sum(
[calendar.monthrange(current_year, elem)[1] for elem in range(current_month, current_month + moths)]
)
print now + days
Solution 36 - Python
Another solution: calculate sum of days in month for next n month and add result to current date.
import calendar
import datetime
def date_from_now(months):
today = datetime.datetime.today()
month = today.month
year = today.year
sum_days = 0
for i in range(int(months)):
month += 1
if month == 13:
month = 1
year += 1
sum_days += calendar.monthrange(year, month)[1]
return datetime.date.today() + datetime.timedelta(sum_days)
print(date_from_now(12)) # if to day is 2017-01-01, output: 2019-01-01
Solution 37 - Python
I used the replace()
method and write this recursive function. the dt
is a datetime.datetime
object:
def month_timedelta(dt, m):
y = m // 12
dm = m % 12
if y == 0:
if dt.month + m <= 12:
return dt.replace(month = dt.month + m)
else:
dy = (dt.month + m) // 12
ndt = dt.replace(year=dt.year + dy)
return ndt.replace(month=(ndt.month + m) % 12)
else:
return month_timedelta(dt.replace(year=dt.year + y),dm)
Solution 38 - Python
My implementation based on taleinat's answer:
import datetime
import calendar
def add_months(orig_date, month_count = 1):
while month_count > 12:
month_count -= 12
orig_date = add_months(orig_date, 12)
new_year = orig_date.year
new_month = orig_date.month + month_count
# note: in datetime.date, months go from 1 to 12
if new_month > 12:
new_year += 1
new_month -= 12
last_day_of_month = calendar.monthrange(new_year, new_month)[1]
new_day = min(orig_date.day, last_day_of_month)
return orig_date.replace(year=new_year, month=new_month, day=new_day)
With this function you can add as many months as you'd like.
from datetime import date
dt = date(2021, 1, 31)
print(add_months(dt, 49))
returns
2025-02-28
Solution 39 - Python
My modification to Tony Diep's answer, possibly marginally more elegant (Python 2 of course, matching the date of the question & original answers, for Python 3 modify as necessary, including /
to //
at least):
def add_months(date, months):
month = date.month + months - 1
year = date.year + (month / 12)
month = (month % 12) + 1
day = date.day
while (day > 0):
try:
new_date = date.replace(year=year, month=month, day=day)
break
except:
day = day - 1
return new_date
adds months according to a 'business needs' interpretation that dates mapping beyond the end of the month, should map to the end of the month rather than into the following month.
Solution 40 - Python
In this function, n can be positive or negative.
def addmonth(d, n):
n += 1
dd = datetime.date(d.year + n/12, d.month + n%12, 1)-datetime.timedelta(1)
return datetime.date(dd.year, dd.month, min(d.day, dd.day))
Solution 41 - Python
We probably should use dateutil.relativedelta
however for academic interest I will just add that before I discovered it I was goint to use this:
try:
vexpDt = K.today.replace(K.today.year + (K.today.month+6)//12, (K.today.month+5)%12+1, K.today.day)
except:
vexpDt = K.today.replace(K.today.year + (K.today.month+6)//12, (K.today.month+6)%12+1, 1) - timedelta(days = 1)
it seems quite simple but still catches all the issues like 29,30,31
it also works for - 6 mths by doing -timedelta
nb - don't be confused by K.today its just a variable in my program
Solution 42 - Python
def addDay(date, number):
for i in range(number)
#try to add a day
try:
date = date.replace(day = date.day + 1)
#in case it's impossible ex:january 32nd add a month and restart at day 1
except:
#add month part
try:
date = date.replace(month = date.month +1, day = 1)
except:
date = date.replace(year = date.year +1, month = 1, day = 1)
For everyone still reading this post. I think this code is way clearer, especially compared to code using modulo(%).
Sorry for any grammatical error, english is so not my main language
Solution 43 - Python
This is what I do when I need to add months or years and don't want to import more libraries.
import datetime
__author__ = 'Daniel Margarido'
# Check if the int given year is a leap year
# return true if leap year or false otherwise
def is_leap_year(year):
if (year % 4) == 0:
if (year % 100) == 0:
if (year % 400) == 0:
return True
else:
return False
else:
return True
else:
return False
THIRTY_DAYS_MONTHS = [4, 6, 9, 11]
THIRTYONE_DAYS_MONTHS = [1, 3, 5, 7, 8, 10, 12]
# Inputs -> month, year Booth integers
# Return the number of days of the given month
def get_month_days(month, year):
if month in THIRTY_DAYS_MONTHS: # April, June, September, November
return 30
elif month in THIRTYONE_DAYS_MONTHS: # January, March, May, July, August, October, December
return 31
else: # February
if is_leap_year(year):
return 29
else:
return 28
# Checks the month of the given date
# Selects the number of days it needs to add one month
# return the date with one month added
def add_month(date):
current_month_days = get_month_days(date.month, date.year)
next_month_days = get_month_days(date.month + 1, date.year)
delta = datetime.timedelta(days=current_month_days)
if date.day > next_month_days:
delta = delta - datetime.timedelta(days=(date.day - next_month_days) - 1)
return date + delta
def add_year(date):
if is_leap_year(date.year):
delta = datetime.timedelta(days=366)
else:
delta = datetime.timedelta(days=365)
return date + delta
# Validates if the expected_value is equal to the given value
def test_equal(expected_value, value):
if expected_value == value:
print "Test Passed"
return True
print "Test Failed : " + str(expected_value) + " is not equal to " str(value)
return False
# Test leap year
print "---------- Test leap year ----------"
test_equal(True, is_leap_year(2012))
test_equal(True, is_leap_year(2000))
test_equal(False, is_leap_year(1900))
test_equal(False, is_leap_year(2002))
test_equal(False, is_leap_year(2100))
test_equal(True, is_leap_year(2400))
test_equal(True, is_leap_year(2016))
# Test add month
print "---------- Test add month ----------"
test_equal(datetime.date(2016, 2, 1), add_month(datetime.date(2016, 1, 1)))
test_equal(datetime.date(2016, 6, 16), add_month(datetime.date(2016, 5, 16)))
test_equal(datetime.date(2016, 3, 15), add_month(datetime.date(2016, 2, 15)))
test_equal(datetime.date(2017, 1, 12), add_month(datetime.date(2016, 12, 12)))
test_equal(datetime.date(2016, 3, 1), add_month(datetime.date(2016, 1, 31)))
test_equal(datetime.date(2015, 3, 1), add_month(datetime.date(2015, 1, 31)))
test_equal(datetime.date(2016, 3, 1), add_month(datetime.date(2016, 1, 30)))
test_equal(datetime.date(2016, 4, 30), add_month(datetime.date(2016, 3, 30)))
test_equal(datetime.date(2016, 5, 1), add_month(datetime.date(2016, 3, 31)))
# Test add year
print "---------- Test add year ----------"
test_equal(datetime.date(2016, 2, 2), add_year(datetime.date(2015, 2, 2)))
test_equal(datetime.date(2001, 2, 2), add_year(datetime.date(2000, 2, 2)))
test_equal(datetime.date(2100, 2, 2), add_year(datetime.date(2099, 2, 2)))
test_equal(datetime.date(2101, 2, 2), add_year(datetime.date(2100, 2, 2)))
test_equal(datetime.date(2401, 2, 2), add_year(datetime.date(2400, 2, 2)))
Just create a datetime.date() object, call add_month(date) to add a month and add_year(date) to add a year.
Solution 44 - Python
Using below given function you can get date after/before x months.
from datetime import date
def next_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 = next_month(today, mm)
print(next_date)
Solution 45 - Python
I could not find an exact solution to this question so i'll post my solution in case it may be of any help using stantard Calendar and datetime libs. this works for add and substract months, and accounts for month-end rolls and cases where the final month has less days than the initial one. I also have a more generalized solution if you are looking for more complex manipulation, it adds regular intervals (days, months, years, quarters, semeters, etc) like: '1m', '-9m', '-1.5y', '-3q', '1s' etc.
from datetime import datetime
from calendar import monthrange
def date_bump_months(start_date, months):
"""
bumps months back and forth.
--> if initial date is end-of-month, i will move to corresponding month-end
--> ir inital date.day is greater than end of month of final date, it casts it to momth-end
"""
signbit = -1 if months < 0 else 1
d_year, d_month = divmod(abs(months),12)
end_year = start_date.year + d_year*signbit
end_month = 0
if signbit ==-1:
if d_month < start_date.month:
end_month = start_date.month - d_month
else:
end_year -=1
end_month = 12 - (d_month - start_date.month)
else:
end_month +=start_date.month
if end_month > 12:
end_year +=1
end_month -=12
# check if we are running end-of-month dates
eom_run = monthrange(start_date.year, start_date.month)[1]==start_date.day
eom_month = monthrange((end_year), (end_month))[1]
if eom_run:
end_day = eom_month
else:
end_day = min(start_date.day, eom_month )
return date(end_year, end_month, end_day)
Solution 46 - Python
Use the python datetime module to add a timedelta of six months to datetime.today() .
http://docs.python.org/library/datetime.html
You will of course have to solve the issue raised by Johannes Weiß-- what do you mean by 6 months?