Calculate the date some months into the future or past
Calculating the date when offsetting into the future or past is possible with the timedelta
object in Python's datetime
module. Unfortunately timedelta
doesn't include a months
parameter. So that complicate matters for calculating date changes in terms of months.
To calculate the date some months into the future or past, you will have to find a module that can do that (like arrow, MonthDelta, and dateutil), find some approximate answer on Stack Overflow, or just use this nifty function I came up with:
def another_month(base, delta=1, overflow=False):
"""Get current day and time at some months
into the future or past.
The base date can be a datetime.date or
datetime.datetime object, delta is
the number of months into the future
(positive number) or the past (negative number).
The default delta is 1 month, in the future.
The overflow parameter specify whether the
calculated date should overflow, if the number
of days exceeds the month's range. The default
is False, which keeps the month and adjusts the
date to the last day of the month.
"""
lsum = lambda a, b: (a[0] + b[0], a[1] + b[1])
mch = lambda year, month, dt: lsum(
(year, 1), divmod((month - 1) + dt, 12))
year, month, day = mch(
base.year, base.month, delta) + (base.day,)
while True:
try:
return base.replace(
year=year, month=month, day=day)
except ValueError:
# day is out of range for month
if overflow and delta > 0:
# overflow days to the
# following month
return (another_month(base.replace(
year=year, month=month - 1, day=1)) +
datetime.timedelta(days=day - 1))
elif overflow and delta < 0:
# subtract overflow days from the
# last day of the month
right_month = base.replace(
year=year, month=month, day=1)
td = another_month(
right_month) - right_month
return right_month.replace(
day=td.days - (day - td.days))
else:
# attempt to adjust to the
# end of the month
day = day - 1