Search code examples
pythonpython-dateutil

How to subtract full months from end_date without crossing the month boundary if end_date falls on the last day of a month?


My goal is to subtract 2 full months from a given enddate without crossing the last month boundry when the end date falls on the last day of a month.

For example if end_date is 2011-02-28 and I subtract from it 2 full months, the start date should be the 2011-01-01 since February 2011 has already taken place in full. The one additional month needed would be January 2011. I tried accomplishing this using dateutil.relativedelta like so:

from dateutil.relativedelta import relativedelta
from dateutil import parser


end_date_1 = parser.parse("2011-02-28").date()
end_date_2 = parser.parse("2011-02-15").date()

time_period = relativedelta(months=2)

start_date_1 = end_date_1 - time_period
start_date_2 = end_date_2 - time_period

print(start_date_1)
print(start_date_2)

This gives the following output:

2010-12-28 # should be 2011-01-01
2010-12-15 # correct!

Solution

  • One approach is to check if date is the last day of month

    from dateutil.relativedelta import relativedelta
    from dateutil import parser
    
    
    def start_date(end_date, mdelta):
        next_day = end_date + relativedelta(days=1)  # get the next day to determine if d is the last date of month
        return (next_day if next_day.day == 1 else end_date) + relativedelta(months=mdelta)  # so add relativedelta to d or d1 according to the condition
    
    
    for d in ['2011-02-28', '2011-02-15', '2011-04-30', '2011-01-30']:
        print(start_date(parser.parse(d).date(), -2))
    

    Output:

    2011-01-01
    2010-12-15
    2011-03-01
    2010-11-30