The Python relativedelta() class is useful for calendar-based date calculations.
It can add or subtract months, years, weeks, days, hours and other date or time components.
It is especially useful when working with calendar months because months do not all contain the same number of days.
For example, adding one calendar month to January 31 should produce a valid date in February rather than simply adding 30 or 31 days.
from datetime import date
from dateutil.relativedelta import relativedelta
dt=date(2020, 1, 31)
new_date=dt + relativedelta(months=1)
print(new_date)
Output
2020-02-29
February has 29 days in 2020 because it is a leap year.
relativedelta is available through the python-dateutil package.
If required, install the package using:
python -m pip install python-dateutil
Then import relativedelta:
from dateutil.relativedelta import relativedelta
For the examples on this page, we also use Python date and datetime objects.
Use the plural argument months when you want to add calendar months to an existing date.
from datetime import date
from dateutil.relativedelta import relativedelta
dt=date(2026, 3, 15)
new_date=dt + relativedelta(months=1)
print(new_date)
Output
2026-04-15
new_date=dt + relativedelta(months=4)
print(new_date)
Output
2026-07-15
A relativedelta can also be subtracted from a date.
from datetime import date
from dateutil.relativedelta import relativedelta
dt=date(2026, 8, 20)
new_date=dt - relativedelta(months=1)
print(new_date)
Output
2026-07-20
from datetime import date
from dateutil.relativedelta import relativedelta
dt=date(2026, 9, 5)
new_date=dt - relativedelta(
years=2,
weeks=1
)
print(new_date)
Output
2024-08-29
The difference between singular and plural argument names is important when using relativedelta().
Plural arguments such as:
years
months
days
hours
minutes
seconds
microseconds
represent relative changes.
For example:
dt + relativedelta(days=1)
adds one day to dt.
Singular arguments such as:
year
month
day
hour
minute
second
microsecond
set that component to a specified value.
from datetime import date
from dateutil.relativedelta import relativedelta
dt=date(2019, 9, 23)
# Add one day
print(
dt + relativedelta(days=1)
)
# Set day of month to 1
print(
dt + relativedelta(day=1)
)
Output
2019-09-24
2019-09-01
days=1 adds one day.
day=1 changes the day component to the first day of the same month.
dt=date(2026, 9, 23)
print(
dt + relativedelta(months=1)
)
print(
dt + relativedelta(month=1)
)
Output
2026-10-23
2026-01-23
months=1 means add one month.month=1 means set the month to January.
More than one relative value can be used in the same relativedelta().
from datetime import date
from dateutil.relativedelta import relativedelta
dt=date(2019, 9, 23)
change=relativedelta(
years=1,
months=2,
days=3
)
new_date=dt + change
print(new_date)
Output
2020-11-26
The same approach can be used with a
datetime object.
from datetime import datetime
from dateutil.relativedelta import relativedelta
dt=datetime(
2019,
9,
23,
14,
48,
35,
124959
)
change=relativedelta(
years=1,
months=2,
days=3,
hours=23,
minutes=56,
seconds=57,
microseconds=324534
)
print(dt + change)
Output
2020-11-27 14:45:32.449493
Another useful feature of relativedelta() is calculating the calendar difference between two dates.
Pass the later date first and the earlier date second.
from datetime import date
from dateutil.relativedelta import relativedelta
start=date(2020, 5, 15)
end=date(2025, 8, 31)
difference=relativedelta(
end,
start
)
print("Years:", difference.years)
print("Months:", difference.months)
print("Days:", difference.days)
Output
Years: 5
Months: 3
Days: 16
The difference between two dates can be used to calculate age in years, months and days.
from datetime import date
from dateutil.relativedelta import relativedelta
today=date(2026, 9, 5)
dob=date(1996, 5, 15)
age=relativedelta(
today,
dob
)
print("Years:", age.years)
print("Months:", age.months)
print("Days:", age.days)
Output
Years: 30
Months: 3
Days: 21
For a live age calculation, replace the fixed value of today with:
today=date.today()
Month-end dates show why calendar-aware calculations are useful.
Suppose we try to create the next month manually:
from datetime import date
dt=date(2019, 1, 31)
new_date=date(
dt.year,
dt.month + 1,
dt.day
)
print(new_date)
This raises a
ValueError
because February 31 is not a valid date.
ValueError: day is out of range for month
from datetime import date
from dateutil.relativedelta import relativedelta
dt=date(2019, 1, 31)
new_date=dt + relativedelta(
months=1
)
print(new_date)
Output
2019-02-28
dt=date(2020, 1, 31)
new_date=dt + relativedelta(
months=1
)
print(new_date)
Output
2020-02-29
The result uses the valid last day of February.
Python's
timedelta()
is useful for calculations based on fixed units such as days, seconds and microseconds.
However, timedelta() does not provide a calendar-month argument because calendar months have different lengths.
from datetime import date, timedelta
dt=date(2019, 1, 31)
new_date=dt + timedelta(
days=30
)
print(new_date)
Output
2019-03-02
from datetime import date
from dateutil.relativedelta import relativedelta
dt=date(2019, 1, 31)
new_date=dt + relativedelta(
months=1
)
print(new_date)
Output
2019-02-28
Thirty days and one calendar month are not always the same.
We can calculate the calendar difference between a date and January 1 of the next year.
from datetime import date
from dateutil.relativedelta import relativedelta
today=date(2019, 9, 21)
new_year=date(
today.year + 1,
1,
1
)
remaining=relativedelta(
new_year,
today
)
print("Months:", remaining.months)
print("Days:", remaining.days)
Output
Months: 3
Days: 11
New Year Countdown with Hours, Minutes and Seconds
relativedelta() can also calculate dates based on weekdays.
Weekday constants such as MO, TU and SU can be imported with relativedelta.
from datetime import date
from dateutil.relativedelta import relativedelta, MO, TU, SU
dt=date(2019, 9, 22)
# Second Monday from this date
print(
dt + relativedelta(
weekday=MO(2)
)
)
# Second Monday of the month
print(
dt + relativedelta(
day=1,
weekday=MO(2)
)
)
# Previous second Tuesday
print(
dt + relativedelta(
weekday=TU(-2)
)
)
Output
2019-09-30
2019-09-09
2019-09-10
print(
dt + relativedelta(
weekday=SU(+1)
)
)
Output
2019-09-22
The starting date is already a Sunday. Therefore, SU(+1) returns the same date.
When several date and time components are supplied, they are applied in this order:
For each component, an absolute singular value such as day=1 is applied before the corresponding relative plural value such as days=2.
The weekday rule is applied after these date and time components.
relativedelta() supports calendar-based date calculations.months= to add or subtract months.years= to add or subtract years.days= to add or subtract days.months and days represent relative changes.month and day set date components.relativedelta(end, start) can calculate a calendar difference in years, months and days.timedelta() is useful for fixed durations, while relativedelta() is useful for calendar months and years.Author & Instructor at plus2net
I write and maintain practical tutorials on Python, PHP, SQL, JavaScript, HTML, jQuery, and web development at plus2net. The tutorials focus on clear explanations, working examples, and code that readers can test and adapt while learning.
23-07-2020 | |
| Thanks for this tutorial was really helpful... | |
26-11-2020 | |
| Very helpful especially the rrule entry. | |