String Representations
00:00 In this lesson, I’m going to tell you about string representations of time in Python. This is kind of on the far end of the continuum that I’ve been talking about for Python time object representations.
00:12 Strings are the most readable for human beings, but they’re the hardest to operate on for machines. When you craft a good string representation, what’s important is that you need to include all of the information that a user needs to interact with your application, but only that information that’s totally necessary.
00:29 That’s going to be the focus of this lesson.
00:33
There are three useful functions that I want to show you for time string conversion. The first is time.asctime
, which simply takes in an optional struct_time
or time tuple object, and just returns the timestamp, which is kind of a basic formatted string for the time.
00:51
strftime()
(“string format time’), in a kind of opposition to that, is a much more flexible, but also more labor-intensive, way to get a string version of a time, because you have to pass in a directive string, I’ll explain that in a little bit, and then a struct_time
.
01:05
It returns the specified string version based on what you pass in as the directive. time.strptime
(“string parse time”) just does the opposite, where it takes in an already formatted string and the directive that was used to format that string, and it returns the struct_time
object based on that data.
01:23
If you pass in no directive, it will assume that this time string is in timestamp format, so you can pass the result of time.asctime()
, to time.strptime
without any directive, and you’ll get a correct struct_time
object out of that.
01:37 Let’s take a look at these directives in a little more depth. The directives, also called format strings, are essentially just a language of special characters that allows you to create format strings, which are combinations of normal characters and these special format characters, which then give an output of some date or time format.
02:00
And so, for example, if I pass in "%a, %B %d"
I get abbreviated weekday for little a
,
02:09
I get the full month name for big B
, and then I get the zero-padded decimal day for %d
. And of course, the comma in here just stays in its same place because it’s not a special character, and the same goes for this "%m/%d/%Y"
(“month/day/year”) format, where the slashes stay in the same place. And then, of course, down here all of the words and other letters stay in the same place, except for the things directly following the percent sign.
02:35
So it’s a very flexible language and it works a lot like C’s printf()
syntax if you’re familiar with that. If you’re not, that’s not a big deal, just know that these format characters are directly substituted with the thing that they correspond to from the date that you are actually using, the date or the time that you’re actually using to create this string.
02:55
So you pass a format string and you pass a time object, and then these fields are automatically filled based on the data from the time object by strftime
, or vice versa, they’re parsed by strptime
, so that’s very convenient.
03:10
Let’s move over into the Python REPL and take a look at how this works in practice. As usual, let’s start out by importing time
.
03:18
The first function I want to show you is the simplest, which is just time.asctime
. As you’ll remember from the previous slides, it takes in an optional time tuple, but if you don’t pass anything in it will just use the current local time and convert that to a timestamp, as you can see here. So it’s Monday, May 4th, “May the 4th be with you,” and it is 13:40 in the afternoon with 13 seconds gone by in the year 2020.
03:45 This gets you pretty much all the information you could want to know about the date in a kind of passing glance of the date and time, but it really is not very flexible, because it doesn’t allow you to include less or more of that information as might be necessary for your application.
04:02 So for example, in a calendar application, it wouldn’t make much sense to have an abbreviated month, and you might also want to include the option to have 12-hour time for users in countries that don’t tend to use 24-hour time.
04:16
Maybe you might also want to have the day of the week or something like that, so there’s a lot of information that you can either add or delete from this, that asctime
doesn’t allow you to do.
04:25
That’s where time.strftime()
comes in, and as you remember, you need to pass in a format string. I’ll start off with something simple, just the year, the month, and the day.
04:36 It also takes in an optional second parameter, and just to show you that this is in fact the same, I’m going to just pass this explicitly, even though this is what it will default to anyway. And as you can see, I get the year 2020, the month is the 5th month and the day is the 4th day.
04:54 But maybe you want a more verbose string representation, more suitable for a more text-based application, and so you might say something like, “In the year,
05:05
%Y
, it was the warm spring month of %m
05:15
on the day, %d
.” And I don’t need to pass this parameter in. And so, “In the year 2020, it was a warm spring month of 05 on the 04 day.” But this isn’t super helpful, because obviously “this warm spring month of 05,” that doesn’t tell you much, and so what you might want to do instead is replace this with a capital B
, which will give the full month name, and that might be more useful.
05:38
And then you could add really any number of different things in here. You could put in all sorts of different characters, but I’ll let you play around with that on your own time, especially by looking at the time
module documentation, to find all of these different format characters you can have to make your time output really pretty. So that’s good, and it gives us a way to have all, but only the necessary, information to convey in your application. Now, if you want to reverse this, you can use strptime()
.
06:06 And as I mentioned in the slides a second ago, if you don’t give it any particular format argument, it will just assume that the string passed in is a timestamp.
06:16
And so I’ll just use time.asctime()
as the string parameter and then I won’t pass in a format parameter. As you can see, this just gives me the current time as a struct_time
.
06:27
So this is kind of a super, super roundabout way to just say time.localtime()
. And as you can see, these turn out to be almost exactly the same thing and the “almost” is just because I called them at different times.
06:37
So that’s how you can parse a timestamp, and then if you want to parse something more complicated, you could do something like this, where you give it a string, and let’s say something like 2020, let’s do the string that I did up here, "2020-05-04"
and then I have to give it the format string that I used there, which was "%Y-%m-%d"
and as you can see, it will just give me the struct_time
object, but of course what you might realize already is that you might lose some information when you do something like this. So strptime()
is super useful, but you also have to be careful because, in this representation, I don’t give an hour, a minute, a second, a weekday, anything like that.
07:21
The weekday is parsed, but I don’t give an hour, a minute, or a second, or anything like that, and I don’t specify whether the time is daylight savings. And so you lose, or you don’t lose information, but there is information that a struct_time
can convey that this time representation doesn’t actually do justice to.
07:37
And so you have to be careful with that when you’re working with these times. I want to show you one more thing here, which is how asctime()
and strftime()
respond differently to changes in locale information. Let me just clear my screen real quick.
07:53
What I want to show you is how, if you change the locale, it can change the output of your string formatting functions, but not for all of them. So, what I want to do first, before I change my locale, is I’ll just show you, I have to import time
, of course, time.asctime
, and then time.strftime
.
08:14
And what I’m going to do is I’m going to just use the "%c"
directive, which just returns a locale-specific timestamp. So as you can see, these both have the same exact format, but now if I change my locale, so I’m going to say locale.setlocale
, and I have to pass in a category, so it’s going to be category.LC_TIME
, so the time section of the locale, and if you want more information about this, I would say your best bet is to go to the locale
documentation, just because there’s a lot more to it than I can explain here, but I’m going to set it to the German locale, "de_DE"
.
08:51
And then what I can do is I’ll show you, first, asctime
, and as you can see, this just doesn’t change at all from what it was with the other locale, which was English USA. That was my first locale. I didn’t actually print it out, but that’s what it was. It was "en_US"
.
09:10
So that doesn’t change, the asctime
, but if I do time.strftime
and I pass it in this "%c"
directive, then that actually does change to reflect the differences in spelling from the German locale. So “Mai” as opposed to “May”, and “Montag”, as opposed to “Monday”, and they have different abbreviations in the different languages.
09:33
So you can see that strftime()
is actually sensitive to locale-specific data. And you can see this, as well, if I do something like just, I’ll say, let’s do the full month name. And as you can see, that’s "Mai"
, so time.strftime
is sensitive to the locale.
09:51 That’s something that’s really important to note when you’re using these functions: you want to always make sure you know what is going to be changing based on the locale of your user. With that in mind, in the next lesson, I’m going to go through just a couple of quick little functions that the time module offers to work with performance in Python.
10:11 That’s going to be measuring performance with a precision time counter, and then also sleeping your current thread execution and the different benefits that that can have.
Become a Member to join the conversation.