Python time in Data Structures
In this lesson, I’m going to talk to you about the different data structures you can use to represent time in Python. We’ve already talked about Python time as a floating-point number of seconds, and the
struct_time object has come up already in multiple different contexts throughout this series, but I haven’t really made it clear how these structures relate to one another, or what kinds of advantages and disadvantages you might find from each of these data structures. And that’s what I’ll do in this lesson.
00:29 What I really want to set up to help you understand the different representations of time as data in Python is this idea of Python time representation as a continuum.
00:40 And this is a continuum that you often come across in computer science context, which is an inverse relationship between human readability and then ease of machine operation. So for example, a floating-point number of seconds is very difficult for a human to understand as time.
00:56 I don’t have any idea what the current time is as a number of seconds from January 1st, 1970. And I just don’t really have any reason to think that way.
01:05 But for a computer, they’re very, very easy to operate on and to store, and so at the base representation, that’s the most convenient way to store things for a computer.
01:13 And then you move on all the way up through tuples, which give a little bit more readability and a little bit less ease of operation, or are a little bit more difficult to operate on.
01:22 And then, finally, you get all the way up to strings, which are the most readable way to represent time, for humans to actually see and understand, but they’re the hardest for machines to operate on.
01:33 And so this kind of continuum idea is going to come up again and again, as I go through these different data structures and throughout the rest of the series.
So the first representation of time that you haven’t seen yet is Python time as a tuple, and this is a very basic idea. It’s a tuple with nine fields, and the fields correspond to different aspects of the time. So the idea is pretty simple: instead of having this one giant number of seconds, you divide it up into a bunch of different numbers, which then give you information about the actual time that you’re supposed to be seeing. And the
struct_time, as you may have noticed is something that you’ve seen already before, the
struct_time has all of these same fields, they just have nice string names for those fields, and it makes use of the
collections.namedtuple to provide even a little bit more structure and readability to this idea of time as a tuple.
There are a couple of new useful functions that you should make note of, which are ones that interact with tuples or structs, and then return the time in seconds. So those are
time.mktime, and then
calendar.timegm. And I’ll explain over in the REPL why you actually use a different module for this one.
02:49 So these are the two functions that you can pass tuples or structs, and actually get a time. So let’s head over into the REPL.
The first thing I want to do is construct a basic time tuple, and I’ve actually included the format here in a comment because it’s difficult to remember, and so that’s really a reason why they invented the
struct_time: because it can be difficult to remember which index in the tuple corresponds to which actual field. But luckily I have that here in a comment. So let’s see, I’m going to define the epoch, actually, and I’ll say the year 1970, the month is 1, the day is 1, the hour is 0, there’s 0 seconds into the day because it’s midnight. The day of the week? Goodness, what was the day of the week? Um, I actually looked this up earlier and it was a Thursday, and since you index from 0 on Monday, so Monday is 0, Tuesday is 1, Wednesday is 2, and Thursday is 3. So that you want to be 3.
And then the day of the year, obviously it’s the 1st day of the year, and then it was not daylight savings time. So if you remember from the slide, the way that you indicate not daylight savings time is zero. So that is the epoch and the first function you can use to take a look at this is you can say
As you know, you don’t pass in seconds, you pass in the tuple, which is the epoch. So now what you might expect is to get 0 seconds, but actually
time.mktime, as you might have seen in this slide, it returns the floating-point time in local time when given a time tuple or struct. My local time, I can check that out by saying
04:28 As you can see, it’s Eastern Standard Time, so five hours behind the actual GMT time. So that’s why this returns 18000.0 seconds—because that’s five hours behind.
And so, this time here that has been returned, if you want the actual epoch, the zero, then what you actually need to do is you need to import calendar and say
calendar.timegm, and then the epoch, and as you can see, that will give you the 0 seconds that might make more sense here. So two things to note: this
time.mktime returns local time and
calendar.timegm returns the GMT from a given time tuple,
05:11 but something else that’s interesting is that I had to import calendar. And the reason for this is a little bit weird, but essentially what it is, is that it was to maintain C compatibility, or perhaps compatibility is not quite the right word, maybe it would be better to say just to be standardized. Standardization.
So the idea was that C actually has this calendar module in it, and so the C calendar, or, the C time module does not have the
it’s instead in a separate module. Python decided to stay consistent with C, and that’s actually the word I was looking for: C consistency is probably a better way to phrase that. Really it’s for historical reasons, but you just have to know that luckily they’re both in the standard library, so there’s no need to worry about installing anything, you can just
import calendar and
import time and not have to worry about any of that. So: Python data structures for time.
What you’ve seen so far are floats, like
time.time(), and that’s a floating-point representation of time. Then you’ve seen tuples, and I’ll make a little comment here. So tuples, which are like epoch,
and this tuple has all of these different fields that represent different aspects of the time. And then, finally, you have the
struct_time, so if you say something like
time.gmtime() you get a
struct_time representing the current time.
It has all of these things, but they’re a little bit easier to access, right? So you can say
time.gmtime().tm_year and just get 2020 out of it, so that’s easier to read and easier to access.
06:46 And then, finally, you’ve seen the ctime actual string here that gives you a timestamp, which is probably the easiest way for a human to read this.
06:57 In the next lesson we’ll get into the final representation of time, which is strings with arbitrary format. I’ll get into how to represent time in a string with any format that you might want.
Become a Member to join the conversation.