When you read a date or time from a text file, user input, or a database, you are likely to get the date information as a string. It is helpful to convert the string to a datetime object since it will allow you to do more advanced functions. In today’s article, I will discuss and show examples of datetime objects in python. Specifically, I will show how to convert a string to a datetime, how to compare and reformat datetime variables, how to work with timezones, and how to extract specific bits of information.
What are Masks?
The mask references the format of the date you are trying to convert. It helps the system understand the input better. Let’s say you have a date you want to convert “7/11/2019”. You can see that it starts with the month, followed by the day of the month, and ends with a 4 digit year. Each part is separated by a forward slash. The datetime library has a special encoding you use to tell it which parts are which. A few examples that we will use today are as follows:
Description | Variable |
---|---|
Year | %Y |
Month | %m |
Day of Month | %d |
Hour of Day (12 hour clock) | %I |
Minute of Hour | %M |
AM/PM | %p |
Hour of day (24 hour clock) | H |
Using the table above to construct our mask, we can describe our string of “7/11/2019” as “%m/%d/%Y”
The above list is by no means comprehensive. A good resource for looking up additional maks variables can be found here.
Converting from a string
Before we can do anything else, we need to convert our string to a datetime object. The main function you will use when converting a string is the strptime function. This stands for String Parse Time. The strptime function takes two input variables:
- The date/time you wish to parse
- The mask of what you are parsing.
Calling the strptime function
We start by importing datetime:
from datetime import datetime
Next, let’s declare a variable and assign a string value to it:
date1 = "7/11/2019"
And lets declare another variable containing our date mask:
datemask = "%m/%d/%Y"
Finally, let’s pass our date and mask into the strptime function:
datetime_object = datetime.strptime(date1, datemask)
if we print the output of datetime_object, we will see that it shows: “2019-07-11 00:00:00”
All of the extra zeroes at the end are because we didn’t pass in a time. Datetime objects have a date and a time value. If you don’t pass in a time value, then the value will always default to midnight.
If we don’t want to use variables, we can hard code the date and/or the mask into the function call:
datetime_object = datetime.strptime('07/11/2019', '%m/%d/%Y')
If we happen to have a timestamp associated with our date, we can add that in as well. This will eliminate that string of zeroes we saw before:
datetime_object = datetime.strptime('07/11/2019 02:45PM', '%m/%d/%Y %I:%M%p')
If we then print our datetime_object:
print(datetime_object)
The output should be:2019-07-11 14:45:00
Notice we have the right date and time now. However, it is not the same format as we passed in. We will address that in the section on formatting dates and times.
Formatting Date and Time
In this section, we will talk about how to take an existing datetime object, and display it in different ways.
Before we start, we need a datetime object to work with:
from datetime import datetime
datetime_object = datetime.today()
The above code will populate the datetime_object variable with an object referencing the date and time right now. If we print datetime_object, you should see something similar to this:2018-03-11 13:12:03.572480
To format this datetime, we need to use masks, just liked we used in the section for converting strings into datetime objects. If we want to display the above datetime as Monday/Day/Year, the mask would be “%m/%d/%Y”.
Let’s pass this mask into the strftime (String Format Time) function along with our datetime_object variable and see what our output is:
mydate = datetime.strftime(datetime_object,'%m/%d/%Y')
print(mydate)
The output should be something similar to “07/11/2019”
Notice we no longer have the time displayed, and we no longer have a string of zeroes stuck onto the end of it.
If we wanted to just see one element, like the year, or the time, we could do that too:
datetime_object = datetime.today() #Show the Year myyear = datetime.strftime(datetime_object,%Y’) print(myyear)
Output: 2018
#Show the time datetime_object = datetime.today() mytime = datetime.strftime(datetime_object,'%m/%d/%Y’) print(mytime)
Output: 1:29PM
Comparing two datetime objects
There are a few ways to compare datetime objects. You may want to know whether one is greater than another, meaning if one came after the other. Or you might want to know how much time has passed between two datetime objects.
In the first comparison, we are looking for a Boolean True or False. In the second comparison, we are looking for the time delta showing us the time difference between the two objects.
Before we begin, we need a couple of datetime objects to work with:
from datettime import datetime datetime1 = datetime.strptime('07/11/2019 02:45PM', '%m/%d/%Y %I:%M%p') datetime2 = datetime.strptime('08/11/2019 05:45PM', '%m/%d/%Y %I:%M%p')
We can use an if statement to compare the two dates:
if datetime1 > datetime2: print(“datetime1 is Greater") if datetime2 > datetime1: print(“datetime2 is Greater")
The above code should output “datetime2 is Greater”
Now that we know that datetime2 is greater, meaning it came after datetime1. It would be nice to know how much later datetime2 is than datetime1.
Lucky for us, it is just like doing some simple math:
timediff = datetime2 - datetime1 print(timediff)
The output should be similar to 31 days, 3:00:00
This indicates there is a 31 day and 3-hour difference between the two timestamps. What if we just want to get a number back indicating a given unit of time? The variable type returned when we subtract one time from another is timedelta. The timedelta object has attributes for each unit of time. If we want to know how many days have passed, we could run:
print(timediff.days)
We will see 31 printed on the screen.
If we want to know how many seconds, we would run:
print(timediff.seconds)
The output would be:10800
If we take 10,800 and divide it by 60 we get 180, then we divide it by 60 again, we get 60. You will notice that this is just showing us the second part of the 31 days and 3 hours.
You will also notice if you try to print timediff.hours or timediff.weeks that it does not work. The only three attributes you can print in this fashion are:
- days
- seconds
- milliseconds
If you want to know how many total hours have passed between datetime1 and datetime2, you will need to do a little math. There is another function we have not used yet called total_seconds(). This function shows you the total number of seconds from the start time to the end time:
#Declare our date varaibles datetime1 = datetime.strptime('07/11/2019 02:45PM', '%m/%d/%Y %I:%M%p') datetime2 = datetime.strptime('08/11/2019 05:45PM', '%m/%d/%Y %I:%M%p') #calculate the difference timediff = datetime2 - datetime1 #convert to seconds seconds = timediff.total_seconds() #Convert seconds to hours (there are 3600 seconds in an hour) hours = (timediff.seconds)/3600 #Show the total print(hours)
The output should be: 747
This indicates that 747 hours have passed between timedate1 and timedate2
Converting timezones
There are a lot of timezones in the world, and it can sometimes be confusing to determine which event happened first. One way to handle this is to always use UTC time (Coordinated Universal Time). But you don’t always have control over that.
There is one prerequisite for this section, and that is pytz. to install that, run:
pip install pytz
– or –
pip3 install pytz
In our example, let’s say you have two airplanes. One is landing in San Francisco (SFO), the other is landing at New York (JFK). One lands at 3:00 PM, San Francisco Time. The other plane lands at 5:00 PM New York time. Which one landed first?
First, we import our libraries
From datetime import datetime From pytz import timezone import pytz
Next, we declare a few variables to represent our timezones:
easterntime = timezone('US/Eastern') pacifictime = timezone('US/Pacific') utctime = pytz.utc
Then we create our two datetime variables:
sfoplanetime = datetime.strptime('07/11/2019 03:00PM', '%m/%d/%Y %I:%M%p') jfkplanetime = datetime.strptime('07/11/2019 05:00PM', '%m/%d/%Y %I:%M%p')
If we print the times, they should look like this:
print(sfoplanetime) print(jfkplanetime)
Output:
2019-07-11 15:00:00
2019-07-11 17:00:00
We can now use the localize function from pytz to assign a timezone to our respective variables:
sfoplanetime = pacifictime.localize(sfoplanetime) jfkplanetime = easterntime.localize(jfkplanetime)
We can verify that it worked by printing out the tzinfo and times again:
print(sfoplanetime) print(sfoplanetime.tzinfo) print(jfkplanetime) print(jfkplanetime.tzinfo)
Output:2019-07-11 15:00:00-07:00US/Pacific2019-07-11 17:00:00-04:00US/Eastern
Notice in the output, it now shows us the name of the timezone when we print the .tzinfo attribute. It also shows us the UTC offset when we print the time. Notice the -07 and -04 for the Pacific and Eastern times.
Now if we compare the two times:
if sfoplanetime < jfkplanetime: print("SFO was First") Else: print(“JFK was First")
The above code will print “JFK was first”. This works because the system now knows about the timezones.
For a list of all time zones in the pytz module, you can run the following code:
import pytz for zone in pytz.all_timezones: print(zone)
Summary
We have discussed how to convert strings into datetime objects, how to compare two different datetime objects, and how to introduce timezone attributes to your datetime attributes.