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:
- Computing of relative deltas (next Monday, next week, last week of the previous month, next five years, etc). π€
- 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
...or if you're on Python3:
pip3 install python-dateutil
Diving In π
Add some time-traveling imports:
from datetime import *
from dateutil.relativedelta import *
import calendar
To get the date and time right now:
NOW = datetime.now()
print(NOW)
# 2019-12-09 11:32:20.295752
...or just the date:
TODAY = date.today()
print(TODAY)
# 2019-12-09
To get next week:
next_week = TODAY + relativedelta(weeks=+1)
print(next_week)
# 2019-12-16
...or next month:
next_month = TODAY + relativedelta(months=+1)
print(next_month)
# 2020-01-09
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
... 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
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
... 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
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
...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
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
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
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)
... 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 π
Sources:
π https://dateutil.readthedocs.io/en/stable/
π https://en.wikipedia.org/wiki/NASA
Top comments (8)
WARNING
Do not use
python3-dateutil
because of trojans. It is not used in this article, but it's a typo-squatter ofpython-dateutil
.Whoa didn't know that bit 'til now! Thanks for the heads up! #todayilearned
It's nice Elijah, cool post by the way!
Thanks man! I appreciate it!
Quiet informative.
Great stuff Elijah!
Thanks Vatsal!
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.
Hey Jaako, thanks for that insight!