Python Dateutil Module
Tags: python, dateutil, todayilearned
Published: 2019-12-09 06:54:11

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. 🤯 


<h2> Getting Started ✊ </h2> 
dateutil can be installed from PyPI using pip:
```
pip install python-dateutil
```
...or if you're on Python3:
```
pip3 install python-dateutil
```
<h2> Diving In 🙌 </h2>

Add some time-traveling imports:
```python
from datetime import *
from dateutil.relativedelta import *
import calendar
```
To get the date and time right now:
```python
NOW = datetime.now()
print(NOW)
# 2019-12-09 11:32:20.295752
```
...or just the date:
```python
TODAY = date.today()
print(TODAY)
# 2019-12-09
```
To get next week:
```python
next_week = TODAY + relativedelta(weeks=+1)
print(next_week)
# 2019-12-16 
```
...or next month:
```python
next_month = TODAY + relativedelta(months=+1)
print(next_month)
# 2020-01-09 
```
We can even *combine* them(next month plus one week):
```python
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):
```python
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*:
```python
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):
```python
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:
```python
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:
```python
# 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`:
```python
# 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`:
```python
# 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 :
```python
# 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:
```python
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