# Datetime In Python

> Learn how to work with the datetime library in Python.

- Canonical: https://dennisokeeffe.com/blog/2021-08-04-datetime-in-python
- Published: 2021-08-04
- Updated: 2021-08-04
- Tags: beginner, python, 100daysofpython

> This is Day 16 of the #100DaysOfPython challenge.

This post will use the standard [`datetime`](https://docs.python.org/3/library/datetime.html) library to work with dates. The final project code can be found [here](https://github.com/okeeffed/hello-python-datetime.git).

## Prerequisites

1. Familiarity with [Pipenv](https://pipenv.pypa.io/en/latest/). See [here](https://blog.dennisokeeffe.com/blog/2020-07-04-abcs-of-pipenv) for my post on Pipenv.
2. Familiarity with [iPython](https://ipython.org/) or interactive shells.

## Getting started

Let's create the `hello-python-datetimes` directory and install the required dependencies.

```s
# Make the `hello-python-datetimes` directory
$ mkdir hello-python-datetimes
$ cd hello-python-datetimes

# Init the virtual environment
$ pipenv --three
$ pipenv install --dev ipython

# Create a folder to place files
$ mkdir src
# Create the required files
$ touch src/datetimes.py
```

We are now ready to begin exploring the standard `datetime` library.

## Playing around with dates and times

Start the shell with `pipenv shell ipython`. This will activate the virtual shell and start an iPython interactive shell.

Now we are free to `from datetime import date` and play around with it:

```py
from datetime import date

date(2021, 8, 4).isocalendar()
# datetime.IsoCalendarDate(year=2021, week=31, weekday=3)

date(2021, 8, 4).isoformat()
# '2021-08-04'

date(2021, 8, 4).ctime()
# 'Wed Aug  4 00:00:00 2021'

date(2021, 8, 4).strftime('%A')
# Wednesday

today = date.today()
# datetime.date(2021, 8, 4)
```

The above displays some of the common methods of the `date` class. More information about the `date` class can be found [here](https://docs.python.org/3/library/datetime.html#datetime-objects).

A lot of what we want to do today is look at how to take some of these methods and get to a point where we can compare dates.

## Comparing dates

We want to write a helper method to check if a given date in the format `YYYY-MM-DD` is before today. Exit the iPython kernel and add the following code to our `src/datetimes.py` file:

```py
from datetime import date


def is_date_before_today(date_str: str):
    """Check if date is before today

    Args:
        date_str (str): String of a date to pass

    Returns:
        bool: Value of if date is before today
    """
    try:
        date_obj = date.fromisoformat(date_str)
        return date_obj < date.today()
    except Exception:
        return False


print(is_date_before_today("2019-01-01"))
print(is_date_before_today("2022-01-01"))
print(is_date_before_today("2021-08-03"))
print(is_date_before_today("2021-08-04"))
```

We can use the `>` and `<` operators to compare dates.

If we now run `python src/datetimes.py` we should see the following output:

```s
$ python src/datetimes.py
True # "2019-01-01"
False # "2022-01-01"
True # "2021-08-03"
False # "2021-08-04"
```

We can see the output reflects a date string that is before today (with today returning `False`).

## Working with now

The `datetime` module from the `datetime` library also has a `now` method that returns the current date and time.

We can use this in combination with `strftime` to get the current date and time in a string format. Update the code to the following:

```py
from datetime import date, datetime


def is_date_before_today(date_str: str):
    """Check if date is before today

    Args:
        date_str (str): String of a date to pass

    Returns:
        bool: Value of if date is before today
    """
    try:
        date_obj = date.fromisoformat(date_str)
        return date_obj < date.today()
    except Exception:
        return False


now = datetime.now()
now_str = now.strftime('%Y-%m-%d')
print(now_str)
print(is_date_before_today(now_str))
```

Running `python src/datetimes.py` will output `2021-08-04` and `False` respectively.

> To learn more about `strftime`, there is a great blog post [here](https://www.programiz.com/python-programming/datetime/strftime).

## Adding and subtracting dates

We can use `datetime.timedelta` to add and subtract dates.

Update our code to the following:

```py
from datetime import date, datetime, timedelta


def is_date_before_today(date_str: str):
    """Check if date is before today

    Args:
        date_str (str): String of a date to pass

    Returns:
        bool: Value of if date is before today
    """
    try:
        date_obj = date.fromisoformat(date_str)
        return date_obj < date.today()
    except Exception:
        return False


now = datetime.now()
now_str = now.strftime('%Y-%m-%d')
print(now_str)
print(is_date_before_today(now_str))

now_subtract_one_day = now - timedelta(days=2)

now_subtract_one_day_str = now_subtract_one_day.strftime('%Y-%m-%d')
print(now_subtract_one_day_str)
print(is_date_before_today(now_subtract_one_day_str))

now_add_one_day = now + timedelta(days=1)

now_add_one_day_str = now_add_one_day.strftime('%Y-%m-%d')
print(now_add_one_day_str)
print(is_date_before_today(now_add_one_day_str))
```

Once again we will `python src/datetimes.py` which will output the following:

```s
$ python src/datetimes.py
2021-08-04
False
2021-08-02
True
2021-08-05
False
```

Awesome, now we know how to add and subtract from dates!

## Summary

Today's post demonstrated how to use the `datetime` module to compare times and determine the current date.

Dates and times are incredibly important to any temporal applications, and the following posts will spend some time looking further into this and how to write tests for this form of functionality.

## Resources and further reading

1. [The ABCs of Pipenv](https://blog.dennisokeeffe.com/blog/2020-07-04-abcs-of-pipenv)
2. [Pipenv](https://pipenv.pypa.io/en/latest/)
3. [Project code](https://github.com/okeeffed/hello-python-datetime)
4. [`strftime`](https://www.programiz.com/python-programming/datetime/strftime)
5. [`datetime`](https://docs.python.org/3/library/datetime.html)

_Photo credit: [`pawel_czerwinski`](https://unsplash.com/@pawel_czerwinski)_
