This question already has an answer here:
How do I calculate the date six months from the current date using the datetime Python module?
Edit – based on your comment of dates being needed to be rounded down if there are fewer days in the next month, here is a solution:
>>> import datetime >>> import calendar >>> >>> def add_months(sourcedate,months): ... month = sourcedate.month - 1 + months ... year = int(sourcedate.year + month / 12 ) ... month = month % 12 + 1 ... day = min(sourcedate.day,calendar.monthrange(year,month)) ... return datetime.date(year,month,day) ... >>> somedate = datetime.date.today() >>> somedate datetime.date(2010, 11, 9) >>> add_months(somedate,1) datetime.date(2010, 12, 9) >>> add_months(somedate,23) datetime.date(2012, 10, 9) >>> otherdate = datetime.date(2010,10,31) >>> add_months(otherdate,1) datetime.date(2010, 11, 30)
Also, if you’re not worried about hours, minutes and seconds you could use
date rather than
datetime. If you are worried about hours, minutes and seconds you need to modify my code to use
datetime and copy hours, minutes and seconds from the source to the result.
This is short and sweet method to add a month to a date using dateutil’s
from datetime import datetime from dateutil.relativedelta import relativedelta date_after_month = datetime.today()+ relativedelta(months=1) print 'Today: ',datetime.today().strftime('%d/%m/%Y') print 'After Month:', date_after_month.strftime('%d/%m/%Y')
After Month: 01/04/2013
A word of warning: relativedelta(months=1) and relativedelta(month=1) have different meanings.
Note: this will requires python-dateutil. to install it you need to run in linux terminal.
sudo apt-get update && sudo apt-get install python-dateutil
Explanation : Add month value in python
Here’s my salt :
current = datetime.datetime(mydate.year, mydate.month, 1) next_month = datetime.datetime(mydate.year + (mydate.month / 12), ((mydate.month % 12) + 1), 1)
Quick and easy 🙂
since no one suggested any solution, here is how i solved so far
year, month= divmod(mydate.month+1, 12) if month == 0: month = 12 year = year -1 next_month = datetime.datetime(mydate.year + year, month, 1)
Use the monthdelta package, it works just like timedelta but for calendar months rather than days/hours/etc.
Here’s an example:
from monthdelta import MonthDelta def prev_month(date): """Back one month and preserve day if possible""" return date + MonthDelta(-1)
Compare that to the DIY approach:
def prev_month(date): """Back one month and preserve day if possible""" day_of_month = date.day if day_of_month != 1: date = date.replace(day=1) date -= datetime.timedelta(days=1) while True: try: date = date.replace(day=day_of_month) return date except ValueError: day_of_month -= 1
To calculate the current, previous and next month:
import datetime this_month = datetime.date.today().month last_month = datetime.date.today().month - 1 or 12 next_month = (datetime.date.today().month + 1) % 12 or 12
from datetime import timedelta try: next = (x.replace(day=1) + timedelta(days=31)).replace(day=x.day) except ValueError: # January 31 will return last day of February. next = (x + timedelta(days=31)).replace(day=1) - timedelta(days=1)
If you simply want the first day of the next month:
next = (x.replace(day=1) + timedelta(days=31)).replace(day=1)
Perhaps add the number of days in the current month using calendar.monthrange()?
import calendar, datetime def increment_month(when): days = calendar.monthrange(when.year, when.month) return when + datetime.timedelta(days=days) now = datetime.datetime.now() print 'It is now %s' % now print 'In a month, it will be %s' % increment_month(now)
What about this one? (doesn’t require any extra libraries)
from datetime import date, timedelta from calendar import monthrange today = date.today() month_later = date(today.year, today.month, monthrange(today.year, today.month)) + timedelta(1)
This implementation might have some value for someone who is working with billing.
If you are working with billing, you probably want to get “the same date next month (if possible)” as opposed to “add 1/12 of one year”.
What is so confusing about this is you actually need take into account two values if you are doing this continuously. Otherwise for any dates past the 27th, you’ll keep losing a few days until you end up at the 27th after leap year.
The values you need to account for:
- The value you want to add a month to
- The day you started with
This way if you get bumped from the 31st down to the 30th when you add one month, you’ll get bumped back up to the 31st for the next month that has that day.
This is how I did it:
def closest_date_next_month(year, month, day): month = month + 1 if month == 13: month = 1 year = year + 1 condition = True while condition: try: return datetime.datetime(year, month, day) except ValueError: day = day-1 condition = day > 26 raise Exception('Problem getting date next month') paid_until = closest_date_next_month( last_paid_until.year, last_paid_until.month, original_purchase_date.day) # The trick is here, I'm using the original date, that I started adding from, not the last one
Well with some tweaks and use of timedelta here we go:
from datetime import datetime, timedelta def inc_date(origin_date): day = origin_date.day month = origin_date.month year = origin_date.year if origin_date.month == 12: delta = datetime(year + 1, 1, day) - origin_date else: delta = datetime(year, month + 1, day) - origin_date return origin_date + delta final_date = inc_date(datetime.today()) print final_date.date()
Similar in ideal to Dave Webb’s solution, but without all of that tricky modulo arithmetic:
import datetime, calendar def increment_month(date): # Go to first of this month, and add 32 days to get to the next month next_month = date.replace(day=1) + datetime.timedelta(32) # Get the day of month that corresponds day = min(date.day, calendar.monthrange(next_month.year, next_month.month)) return next_month.replace(day=day)
I was looking to solve the related problem of finding the date for the first of the following month, regardless of the day in the given date. This does not find the same day 1 month later.
So, if all you want is to put in December 12, 2014 (or any day in December) and get back January 1, 2015, try this:
import datetime def get_next_month(date): month = (date.month % 12) + 1 year = date.year + (date.month + 1 > 12) return datetime.datetime(year, month, 1)
Simplest solution is to go at the end of the month (we always know that months have at least 28 days) and add enough days to move to the next moth:
>>> from datetime import datetime, timedelta >>> today = datetime.today() >>> today datetime.datetime(2014, 4, 30, 11, 47, 27, 811253) >>> (today.replace(day=28) + timedelta(days=10)).replace(day=today.day) datetime.datetime(2014, 5, 30, 11, 47, 27, 811253)
Also works between years:
>>> dec31 datetime.datetime(2015, 12, 31, 11, 47, 27, 811253) >>> today = dec31 >>> (today.replace(day=28) + timedelta(days=10)).replace(day=today.day) datetime.datetime(2016, 1, 31, 11, 47, 27, 811253)
Just keep in mind that it is not guaranteed that the next month will have the same day, for example when moving from 31 Jan to 31 Feb it will fail:
>>> today datetime.datetime(2016, 1, 31, 11, 47, 27, 811253) >>> (today.replace(day=28) + timedelta(days=10)).replace(day=today.day) Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: day is out of range for month
So this is a valid solution if you need to move to the first day of the next month, as you always know that the next month has day 1 (
.replace(day=1)). Otherwise, to move to the last available day, you might want to use:
>>> today datetime.datetime(2016, 1, 31, 11, 47, 27, 811253) >>> next_month = (today.replace(day=28) + timedelta(days=10)) >>> import calendar >>> next_month.replace(day=min(today.day, calendar.monthrange(next_month.year, next_month.month))) datetime.datetime(2016, 2, 29, 11, 47, 27, 811253)
Just Use This:
import datetime today = datetime.datetime.today() nextMonthDatetime = today + datetime.timedelta(days=(today.max.day - today.day)+1)
A solution without the use of calendar:
def add_month_year(date, years=0, months=0): year, month = date.year + years, date.month + months + 1 dyear, month = divmod(month - 1, 12) rdate = datetime.date(year + dyear, month + 1, 1) - datetime.timedelta(1) return rdate.replace(day = min(rdate.day, date.day))
def add_month(d,n=1): return type(d)(d.year+(d.month+n-1)/12, (d.month+n-1)%12+1, 1)
This is what I came up with
from calendar import monthrange def same_day_months_after(start_date, months=1): target_year = start_date.year + ((start_date.month + months) / 12) target_month = (start_date.month + months) % 12 num_days_target_month = monthrange(target_year, target_month) return start_date.replace(year=target_year, month=target_month, day=min(start_date.day, num_days_target_month))
def month_sub(year, month, sub_month): result_month = 0 result_year = 0 if month > (sub_month % 12): result_month = month - (sub_month % 12) result_year = year - (sub_month / 12) else: result_month = 12 - (sub_month % 12) + month result_year = year - (sub_month / 12 + 1) return (result_year, result_month) def month_add(year, month, add_month): return month_sub(year, month, -add_month) >>> month_add(2015, 7, 1) (2015, 8) >>> month_add(2015, 7, 20) (2017, 3) >>> month_add(2015, 7, 12) (2016, 7) >>> month_add(2015, 7, 24) (2017, 7) >>> month_add(2015, 7, -2) (2015, 5) >>> month_add(2015, 7, -12) (2014, 7) >>> month_add(2015, 7, -13) (2014, 6)
example using the time object:
start_time = time.gmtime(time.time()) # start now #increment one month start_time = time.gmtime(time.mktime([start_time.tm_year, start_time.tm_mon+1, start_time.tm_mday, start_time.tm_hour, start_time.tm_min, start_time.tm_sec, 0, 0, 0]))
My very simple solution, which doesn’t require any additional modules:
def addmonth(date): if date.day < 20: date2 = date+timedelta(32) else : date2 = date+timedelta(25) date2.replace(date2.year, date2.month, day) return date2