DEV Community

Cover image for Python Dateutil Module
Elijah Jeremiah L. Barba
Elijah Jeremiah L. Barba

Posted on • Updated on

Python Dateutil Module

Python has the built-in datetime module which is used for manipulating dates and times from simple to complex ways. While this may be enough for a number of use cases, the dateutil module provides powerful extensions to this. Some cool features that we would be exploring are:

  1. Computing of relative deltas (next Monday, next week, last week of the previous month, next five years, etc). 🤔
  2. Computing of relative deltas between two given dates and/or datetime objects. 🤯

Getting Started ✊

dateutil can be installed from PyPI using pip:

pip install python-dateutil
Enter fullscreen mode Exit fullscreen mode

...or if you're on Python3:

pip3 install python-dateutil
Enter fullscreen mode Exit fullscreen mode

Diving In 🙌

Add some time-traveling imports:

from datetime import *
from dateutil.relativedelta import *
import calendar
Enter fullscreen mode Exit fullscreen mode

To get the date and time right now:

NOW = datetime.now()
print(NOW)
# 2019-12-09 11:32:20.295752
Enter fullscreen mode Exit fullscreen mode

...or just the date:

TODAY = date.today()
print(TODAY)
# 2019-12-09
Enter fullscreen mode Exit fullscreen mode

To get next week:

next_week = TODAY + relativedelta(weeks=+1)
print(next_week)
# 2019-12-16 
Enter fullscreen mode Exit fullscreen mode

...or next month:

next_month = TODAY + relativedelta(months=+1)
print(next_month)
# 2020-01-09 
Enter fullscreen mode Exit fullscreen mode

We can even combine them(next month plus one week):

next_month_plus_one_week = TODAY + relativedelta(months=+1, weeks=+1)
print(next_month_plus_one_week)
# 2020-01-16 
Enter fullscreen mode Exit fullscreen mode

... and even add time(next month plus one week at 1pm):

added_time = TODAY + relativedelta(months=+1, weeks=+1, hour=13)
print(added_time)
# 2020-01-16 13:00:00
Enter fullscreen mode Exit fullscreen mode

Of course we can go backwards:

last_week = TODAY + relativedelta(weeks=-1)
print(last_week)
# 2019-12-02

last_month = TODAY + relativedelta(months=-1)
print(last_month)
# 2019-11-09
Enter fullscreen mode Exit fullscreen mode

... and we can mix things up a bit(one month before one year):

one_month_before_one_year = TODAY + relativedelta(years=+1, months=-1)
print(one_month_before_one_year)
# 2020-11-09
Enter fullscreen mode Exit fullscreen mode

BTW adding one month will never cross the month boundary:

print(date(2020, 1, 27) + relativedelta(months=+1))
# 2020-02-27
print(date(2020, 1, 31) + relativedelta(months=+1))
# 2020-02-29 (2020 is a leap year! #todayilearned)
print(date(2020, 1, 31) + relativedelta(months=+2))
#2020-03-31
Enter fullscreen mode Exit fullscreen mode

...this logic also applies for years, even on leap years:

# Note that 2020 is a leap year
print(date(2020, 2, 28) + relativedelta(years=+1))
# 2021-02-28
print(date(2020, 2, 29) + relativedelta(years=+1))
# 2021-02-28

# Subtracting 1 year from Feb 29 2020 will print Feb 28 2019
print(date(2020, 2, 29) + relativedelta(years=-1))
# 2019-02-28
Enter fullscreen mode Exit fullscreen mode

We can also make use of weekdays:

# Note that TODAY is a Monday
this_TGIF = TODAY + relativedelta(weekday=FR)
print(this_TGIF)
# 2019-12-13

# Tuesday of next week, not tomorrow
next_tuesday = TODAY + relativedelta(weeks=+1, weekday=TU)
print(next_tuesday)
#2019-12-17

# Making use of the calendar import
next_tuesday_calendar = TODAY + relativedelta(weeks=+1, weekday=calendar.TUESDAY)
print(next_tuesday_calendar)
# 2019-12-17
Enter fullscreen mode Exit fullscreen mode

We can also find a date using yearday:

# Get the 237th day of 2020
print(date(2020, 1, 1) + relativedelta(yearday=237))
# 2020-08-24
Enter fullscreen mode Exit fullscreen mode

Getting the difference of two dates is pretty straightforward :

# Setting the date
# year - month - day - hour - minutes
nasa_birthday = datetime(1958, 7, 29, 0, 0)
age_of_nasa = relativedelta(TODAY, nasa_birthday)
print(age_of_nasa)
# relativedelta(years=+61, months=+4, days=+10)
Enter fullscreen mode Exit fullscreen mode

... and formatting is also easy-peasy:

print('It has been {} years, {} months and {} days since the birth of NASA 🚀'
      .format(age_of_nasa.years,
              age_of_nasa.months,
              age_of_nasa.days,))
#It has been 61 years, 4 months and 10 days since the birth of NASA 🚀
Enter fullscreen mode Exit fullscreen mode

Sources:
🐍 https://dateutil.readthedocs.io/en/stable/
🚀 https://en.wikipedia.org/wiki/NASA

Discussion (8)

Collapse
mburszley profile image
Maximilian Burszley • Edited on

WARNING

Do not use python3-dateutil because of trojans. It is not used in this article, but it's a typo-squatter of python-dateutil.

Collapse
ejbarba profile image
Elijah Jeremiah L. Barba Author • Edited on

Whoa didn't know that bit 'til now! Thanks for the heads up! #todayilearned

Collapse
kojiadrianojr profile image
JARVUC

It's nice Elijah, cool post by the way!

Collapse
ejbarba profile image
Elijah Jeremiah L. Barba Author

Thanks man! I appreciate it!

Collapse
vatsal029 profile image
Vatsal Gala

Quiet informative.
Great stuff Elijah!

Collapse
ejbarba profile image
Elijah Jeremiah L. Barba Author

Thanks Vatsal!

Collapse
jaakofalltrade profile image
Jaako

Excellent job Elijah, by the way I think it would be a whole lot shorter if you used f-strings instead of the .format method.

Collapse
ejbarba profile image
Elijah Jeremiah L. Barba Author

Hey Jaako, thanks for that insight!