Working with Time Zones in Python

45 minutes
  • 2 Learning Objectives

About this Hands-on Lab

The due dates stored in the database are naive datetimes. That means they do not have a time zone associated with them. So while we can see a date and time, the datetime object is unaware of *when* that datetime is. What time zone at almost midnight are we talking about?

Standard practice is to store all due dates in UTC format, then change them to the relevant time zone as needed.

**pytz** is a 3rd-party application that helps with time zones, including daylight savings. From their documentation: *pytz brings the Olson tz database into Python. This library allows accurate and cross platform timezone calculations using Python 2.4 or higher. It also solves the issue of ambiguous times at the end of daylight saving time, which you can read more about in the Python Library Reference (`datetime.tzinfo`).*

You will need basic Python programming and datetime skills for this lab:
– [Certified Associate in Python Programming Certification](https://linuxacademy.com/cp/modules/view/id/470)
– [Python’s datetime](https://docs.python.org/3/library/datetime.html#strftime-and-strptime-format-codes)
– [pytz](http://pytz.sourceforge.net/)

Learning Objectives

Successfully complete this lab by achieving the following learning objectives:

Make Due Dates Timezone Aware

Using the SQLite applications you have already developed you pull all the datetimes and book titles from the db.

Run python timezones.py. This will result in an AssertionError. There are two sections that must be fixed to pass the assertion.

In this first section, you must make the due dates aware datetime objects by adding time zone information to the datetime object. The time zone added should the time zone indicated for a book title.

You create a time zone object with pytz.

my_timezone = pytz.timezone(<time zone name>)

Then make the due date aware of that time zone. This is done by replacing the None time zone with the real time zone. This does not change the due date, just makes it aware of its time zone:

aware_due_date = due_date.replace(my_timezone)

We need to install pytz, so run pip3 install pytz. Now make those times aware of their time zone:

import pytz
from datetime import datetime

# due date data from db
title_due_dates = [
    ['Oh Python! My Python!', '2020-11-15 23:59:59'], 
    ['Fun with Django', '2020-06-23 23:59:59'], 
    ['When Bees Attack! The Horror!', '2020-12-10 23:59:59'], 
    ["Martin Buber's Philosophies", '2020-07-12 23:59:59'], 
    ['The Sun Also Orbits', '2020-10-31 23:59:59']
]

# dictionary matching the timezone value to book title
title_time_zones = {
    'Oh Python! My Python!': 'US/Central', 
    'Fun with Django': 'US/Pacific', 
    'When Bees Attack! The Horror!': 'Europe/London', 
    "Martin Buber's Philosophies": 'Australia/Melbourne', 
    'The Sun Also Orbits': 'Europe/Paris'
}

# when the db due_date string is converted to a datetime object it is naive
# it does not contain timezone info
# make the due_date timezone aware with `<due_date>.replace(timezone)`
# make the timezone the same as indicated in `title_time_zones`
# this makes the book due just before midnight local time
aware_title_due_dates = {}
for book in title_due_dates:
    book_timezone = pytz.timezone(title_time_zones[book[0]])
    naive_date_due = datetime.strptime(book[1], "%Y-%m-%d %H:%M:%S")
    aware_date_due = naive_date_due.replace(tzinfo=book_timezone)
    aware_title_due_dates[book[0]] =  aware_date_due

# remaining code omitted-used in step 2.
Turn All Due Date to UTC

We now have a dictionary of aware datetimes by book author timezone. These aware datetimes are set for essentially midnight in the author’s timezone.

When storing due dates, it is a standard to store the datetime in UTC and convert to the user’s timezone on the fly. So now we need to change the timezone on the author’s due date to UTC and make it a text string for storage in the database.

# code prior to this omitted

# aware_title_due_dates has the due date in the author's timezone
# following good db practice we will store the dates as UTC and
# only convert when necessary to time zone needed
# update `title_due_dates` with the due_date in UTC time
for book in title_due_dates:
    utc_due_date = aware_title_due_dates[book[0]].astimezone(pytz.utc)
    utc_due_date_string = utc_due_date.strftime("%Y-%m-%d %H:%M:%S %Z%z")
    book[1] = utc_due_date_string

# we can now use aware_title_due_dates for updating the db

Run python timezones.py.

Congrats! You have shown basic understanding of datetimes and timezones. This skill will be necessary if you work for a compant that has an application used worldwide.

Additional Resources

Atlantic Publishing ran into a problem caused by an oversight. The due date in the database signifies the time relevant to the author's time zone.

This is causing confusion for both the author and the company.

You have been asked to implement best practice for storing datetimes, and must store the due date in UTC, relative to midnight in the author's time zone.

Logging In

There are a couple of ways to get in and work with the code. One is to use the credentials provided in the hands-on lab page, log in with SSH, and use a text editor in the terminal.

The other is using VS Code in a web browser. If you'd like to go this route, then you will need to navigate to the public IP address of the workstation server (provided in the hands-on lab page) on port 8080 (example: http://PUBLIC_IP:8080). Your password will be the same password that you'd use to connect over SSH.

What are Hands-on Labs

Hands-on Labs are real environments created by industry experts to help you learn. These environments help you gain knowledge and experience, practice without compromising your system, test without risk, destroy without fear, and let you learn from your mistakes. Hands-on Labs: practice your skills before delivering in the real world.

Sign In
Welcome Back!

Psst…this one if you’ve been moved to ACG!

Get Started
Who’s going to be learning?