Hint: You can adjust the default video playback speed in your account settings.
Hint: You can set the default subtitles language in your account settings.
Sorry! Looks like there’s an issue with video playback 🙁 This might be due to a temporary outage or because of a configuration issue with your browser. Please see our video player troubleshooting guide to resolve the issue.

Proper Time Zone Support

00:00 Previously, I gave you a quick overview of the course. In this lesson, I’ll be talking about the new zoneinfo library. By default, timestamps created with the datetime module have no time zone information.

00:14 You can add a time zone to a date using the tz attribute in the date/time creation methods. Timestamps without time zone information are called naive. datetime.now() without any parameters returns a naive datetime. By passing in a tz parameter, you can set a time zone to be associated with the timestamp.

00:35 In this case here, I’ve passed in utc. Previous to Python 3.9, the only time zone that came out of the box was UTC. You had to subclass it or use a third-party library in order to use time zones besides UTC.

00:53 Python 3.9 introduces the zoneinfo module. The ZoneInfo class inside of it accesses your computer’s time zone database and makes that information available to you in your code.

01:06 You can specify times zones by name, and there are hundreds of them—including historic values—available. The library also handles the name changes that happen if your time zone switches into Daylight Savings Time.

01:22 Let me start by demonstrating time zones before Python 3.9. These are the modules you’ll need.

01:30 now() returns the current datetime. This is a naive datetime; it does not include time zone information. I can use the timezone module and specify a time zone of utc, and now I have a datetime including time zone information.

01:48 The new feature from Python 3.9 is the ZoneInfo class. I can specify a ZoneInfo using a time zone string. This is the time zone for the west coast of Canada.

02:01 You can use a ZoneInfo object in conjunction with the tz parameter.

02:10 Here’s the current time in Oslo. The .astimezone() function allows you to convert a datetime between time zones.

02:20 Let me just construct a new datetime.

02:27 This one’s in Vancouver. Then I can call .astimezone(), passing in Oslo,

02:36 and I get the same datetime stamp, but in the Oslo time zone. It’s converted it for me. zoneinfo has an available_timezones() function to list everything that’s in the database. There’s a lot there, so I’m not going to show it all to you.

02:54 The number of entries varies from operating system to operating system. What is happening here is zoneinfo is loading a file that comes with your computer.

03:02 I’m running this on a Mac, and at the moment there’s 595 items in the database. My colleague who wrote the article that goes with this course—I believe he was using Linux and he got 609, so you’re going to get variation from place to place.

03:16 There aren’t 595 times zones on the planet, so why is there so much information in the database? This is because it includes historical information. As countries change, as borders change, and as countries change their mind about what time zone they’re in—the data shifts.

03:32 Let me show you an extreme example of this.

03:41 This is the time zone for Christmas Island. You might be wondering why I said Christmas. Well, the name of the zone there is actually the Kiribati spelling of the word Christmas. Kiribati pronounces it closer to “kirismash”, but I’m not going to embarrass myself by attempting that. Christmas Island is near the International Date Line. At the end of 1994, the residents of Christmas Island decided they wanted to shift what time zone they were in.

04:10 They changed which side of the date line they were on in order to minimize the time difference with their primary trading partners. Here’s New Year’s Eve 1994 in UTC.

04:25 Now I’m going to use .astimezone() to convert that to Christmas Island’s time zone, and you’ll notice that that’s showing as December 30th. To make the next bit clearer, I’m going to use the timedelta library to create a variable containing the amount of time in an hour.

04:43 It’ll make some of the math in the next chunk simpler.

04:50 There’s the library. And I’m going to store the amount of a single hour in a variable called hour.

05:02 And this is where the weirdness happens. The original .astimezone() was 1994, December 30th. One hour later, it’s 1995, January 1st. Because Christmas Island decided to switch from one side of the date line to the other at the end of 1994, they lost December 31st. It just disappeared. One hour, it was 1994, December 30th. An hour later, it was 1995.

05:30 You can see the same thing happening by calling .utcoffset() (UTC offset).

05:40 This function returns the timedelta between your current time zone and UTC. The delta on December 30th, 1994 was 50,400 seconds.

06:00 Dividing that by an hour, gives something that’s a little easier to keep in your head. It was -10 hours. The UTC offset the next day…

06:14 was 14 hours. They swapped which side of the International Date Line they were on, and everything moved forward by 24 hours. In addition to historical corner cases, you can also see more typical changes like those caused by Daylight Savings Time. Once again, here’s Vancouver.

06:34 The .tzname() function gives you the short name that is commonly used for a time zone. On October 5th, this time zone is referred to as 'PDT', short for Pacific Daylight Time.

06:52 Later on in the same year, and the short name for this time zone changes to 'PST', for Pacific Standard Time. The zoneinfo database allows you to see all of this.

07:04 As I mentioned before, the ZoneInfo class is getting its time zone information from a database on your computer. Depending on your operating system, the values in that database may be different or could be missing altogether.

07:17 Some computers don’t have this database installed, particularly certain versions of Windows. If you go to use the ZoneInfo class in this case, you’ll get an exception. To make sure all Python programmers are on an equal footing, the folks at Python have also created a tzdata database, so if your operating system doesn’t ship with the database, you can use pip install to get a copy of the database maintained by the Python folks.

07:45 ZoneInfo has also been backported to earlier versions of Python. You can get this code using pip install backports.zoneinfo. If you’re trying to write code that uses this module in Python 3.9 or earlier, you can do a try / except block importing zoneinfo or the backports version of zoneinfo to make sure that you always get the library.

08:09 Here are a few things to keep in mind when using time zones. If you’re trying to record a timestamp that is a civil time, it should include a time zone. Civil times are things like meetings, train times, concerts—the kinds of thing you would put inside of your calendar.

08:26 These kinds of events tend to be related to a location. Keeping the appropriate time zone allows you to store that information with the timestamp. This is particularly useful if your user is traveling.

08:38 If they happen to be in another time zone, they need to know what the appointment was in the time zone they were in. If you aren’t storing the time zone information, things get muddy quickly. Timestamps, on the other hand, should be naive and based on UTC.

08:54 The typical use of timestamps is inside of server logs. You don’t want to be dealing with the changes in Daylight Savings Time, or time zone changes of a server, or where the server is located when you’re trying to timestamp an event.

09:07 UTC is always monotonically increasing. That means the numeric value is always going up. Because of things like Daylight Savings Time, that’s not true of civil times.

09:18 It is possible for an event at 1:30 in the morning to be after an event at 2:00 in the morning in a time zone that uses Daylight Savings Time on the day that it shifts. Because you don’t want to be dealing with this inside of your server logs, stick with a UTC-based timestamp.

09:37 Next up, I’ll introduce you to the new operators for dictionaries.

Become a Member to join the conversation.