Adding years in python

ismail khan picture ismail khan · Sep 26, 2015 · Viewed 17.8k times · Source

If I want to add 100 years in my program, why is it showing the wrong date?

import datetime
stringDate= "January 10, 1920"
dateObject= datetime.datetime.strptime(stringDate, "%B %d, %Y")
endDate= dateObject+datetime.timedelta(days=100*365)
print dateObject.date()
print endDate.date()

Answer

jfs picture jfs · Sep 27, 2015

The number of seconds in a year is not fixed. Think you know how many days are in a year? Think again.

To perform period (calendar) arithmetic, you could use dateutil.relativedelta:

#!/usr/bin/env python
from datetime import date
from dateutil.relativedelta import relativedelta # $ pip install python-dateutil

print(date(1920, 1, 10) + relativedelta(years=+100))
# -> 2020-01-10

To understand, why d.replace(year=d.year + 100) fails, consider:

print(date(2000, 2, 29) + relativedelta(years=+100))
2100-02-28

Notice that 2100 is not a leap year while 2000 is a leap year.

If the only units you want to add is year then you could implement it using only stdlib:

from calendar import isleap

def add_years(d, years):
    new_year = d.year + years
    try:
        return d.replace(year=new_year)
    except ValueError:
        if (d.month == 2 and d.day == 29 and # leap day
            isleap(d.year) and not isleap(new_year)):
            return d.replace(year=new_year, day=28)
        raise

Example:

from datetime import date

print(add_years(date(1920, 1, 10), 100))
# -> 2020-01-10
print(add_years(date(2000, 2, 29), 100))
# -> 2100-02-28
print(add_years(date(2000, 2, 29), 4))
# -> 2004-02-29