Datetime notebook: ATM350, Spring 2026
Meteorological data is inherently time-based. We will have frequent need to parse, assign, and manipulate date and time strings/objects in our data analysis and visualization workflows. We used the date command in our exploration of the bash shell earlier in the course. Python has its own set of date and time tools that are extremely powerful, once you get the hang of it!¶
The datetime module includes the following classes:¶
date
datetime
time
timedelta
timezone
tzinfo
It also includes these associated methods:¶
strftime
strptime
Imports¶
We’ll import some of these various classes as follows, as well as one from a separate Python library that handles time zones:
from datetime import datetime, timedelta
from zoneinfo import ZoneInfoGet the current time by making a call to datetime’s datetime.now method. It produces a datetime object with the year, month, day, hour, minute, second and microsecond.¶
current = datetime.now()currentdatetime.datetime(2026, 3, 13, 0, 23, 51, 222293)print(current)2026-03-13 00:23:51.222293
Notice that we don’t see any time zone in the above output ... i.e., the datetime object we have created is timezone-unaware. In general, just as we like to have meaningful units attached to measurements, we ought to do the same for time-related data. We can do this via Python’s ZoneInfo library. We will create a few different objects, each corresponding to a particular time zone (or region, useful for the many locations that use daylight saving time during the year).¶
tz_utc = ZoneInfo("UTC")
tz_est = ZoneInfo("EST")
tz_eastern = ZoneInfo("America/New_York")Re-generate the current datetime object, this time passing in the optional argument tz to make it timezone-aware.
current = datetime.now(tz=tz_utc)currentdatetime.datetime(2026, 3, 13, 0, 23, 51, 374023, tzinfo=zoneinfo.ZoneInfo(key='UTC'))This datetime object contains a variety of attributes that we can list, as well as reformat.¶
current.year2026current.month3We can use the strftime method on a datetime object in order to produce date/time strings in a specified format.¶
We’ll play around with a few of these options in the cells below, but visit https:// docs .python .org /3 /library /datetime .html #strftime -strptime -behavior for full documentation of strftime!¶
# %A or %a will list the full name of the day of the week:
current.strftime("%A")'Friday'# %y will list the two-digit year, %m, the two-digit month, and %d, the two-digit date:
print(current.strftime("%y"))
print(current.strftime("%m"))
print(current.strftime("%d"))
print(current.strftime("%y%m%d"))26
03
13
260313
Let’s combine the year, month, and day, into a date string we’re used to using in ATM 350! We can define a new object called current_str as the output from our strftime method, still using our the datetime object current we created using the datetime.now() method:¶
current_str = current.strftime("%Y is the year, %m is the month, and %d is the day, and Ross is the man")
print(current_str)2026 is the year, 03 is the month, and 13 is the day, and Ross is the man
Let’s incorporate the two-digit hour into the string representation:
current.strftime("%y%m%d%H")'26031300'What if we wanted to define a more human-friendly string to use; say, in the title of a graphic?
current.strftime("%y%m%d at %HZ")'260313 at 00Z'# Enter your code here:
current.strftime("%d %B %Y at %H%M %Z")'13 March 2026 at 0023 UTC'Click to reveal only AFTER you have tried your own code!
current.strftime("%d %B %Y at %H%M %Z")We can also create datetime objects with any date/time/timezone we want.¶
date_first = datetime(2024,5,14,17,tzinfo=tz_eastern)
date_second = datetime(2024,5,14,16,tzinfo=tz_est)
date_third = datetime(2024,5,15, 0, tzinfo=tz_utc)date_firstdatetime.datetime(2024, 5, 14, 17, 0, tzinfo=zoneinfo.ZoneInfo(key='America/New_York'))print(date_first.year)
print(date_first.month)
print(date_first.hour)
print(date_first.minute)
print(date_first.second)
print(date_first.tzinfo)2024
5
17
0
0
America/New_York
We can also use some basic arithmetic to calculate time between dates!¶
dt1 = date_first - date_second
print(f"dt1 = {dt1}")
dt2 = date_third - date_second
print(f"dt2 = {dt2}")dt1 = 0:00:00
dt2 = 3:00:00
Datetime’s timedelta class allows us to easily compute dates and times earlier or later than a base time.¶
Note that these objects are defined as a period of time, rather than a date.¶
t1 = timedelta(weeks = 2, days = 5, hours = 1, seconds = 33)
t2 = timedelta(days = 4, hours = 11, minutes = 4, seconds = 54)
t3 = t1 + t2
print("t3 =", t3)t3 = 23 days, 12:05:27
t1 = timedelta(seconds = 33)
t2 = timedelta(seconds = 54)
t3 = t1 - t2
print("t3 =", t3)
print("t3 =", abs(t3))t3 = -1 day, 23:59:39
t3 = 0:00:21
Timedelta includes a total_seconds() method:¶
t = timedelta(days = 6, hours = 13, seconds = 53, microseconds = 232436)
print(f"total seconds = {t.total_seconds()}" )
print(f"total minutes = {t.total_seconds()/60}")total seconds = 565253.232436
total minutes = 9420.887207266667
Note that months is not a valid timedelta argument!! Why not?¶
t1 = timedelta (months = 1)---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
Cell In[23], line 1
----> 1 t1 = timedelta (months = 1)
TypeError: __new__() got an unexpected keyword argument 'months'However, if our datetime object includes a month, we can compute a time delta in months via the relativedelta function from a separate package, dateutil:¶
from dateutil.relativedelta import relativedelta
current + relativedelta(months=2)datetime.datetime(2026, 5, 13, 0, 23, 51, 374023, tzinfo=zoneinfo.ZoneInfo(key='UTC'))As we learned at the beginning of this notebook, datetime’s datetime class includes the strftime method which takes a datetime object and converts it into a string, which can be formatted. Review from earlier...¶
# current date and time
curtime = datetime.now(tz=tz_utc)
string1 = curtime.strftime("%H:%M:%S")
print("string1:", string1)
string2 = curtime.strftime("%m/%d/%Y, %H:%M:%S")
# mm/dd/YY H:M:S format
print("string2:", string2)
string3 = curtime.strftime("%d/%m/%Y, %H:%M:%S")
# dd/mm/YY H:M:S format
print("string3:", string3)string1: 00:23:52
string2: 03/13/2026, 00:23:52
string3: 13/03/2026, 00:23:52
Conversely, the strptime method takes an appropriately-formatted date/time string and converts it into a datetime object.¶
#Start with a string:
date_string = "10 June, 2023"
print("date_string =", date_string)
#Convert to a date object, making sure to include the appropriate formatting we used in the string:
date_object = datetime.strptime(date_string, "%d %B, %Y")
print("date_object =", date_object)date_string = 10 June, 2023
date_object = 2023-06-10 00:00:00
date_string_2026 = "2026-02-24T00:00:00 UTC"
date_object_2026 = datetime.strptime(date_string_2026, "%Y-%m-%dT%H:%M:%S %Z")
date_object_2026datetime.datetime(2026, 2, 24, 0, 0)date_object_2026.tzinfoWe can assign it the proper timezone:
date_object_2026 = date_object_2026.replace(tzinfo=tz_utc)
date_object_2026datetime.datetime(2026, 2, 24, 0, 0, tzinfo=zoneinfo.ZoneInfo(key='UTC'))Calculate a new date and convert it into its string representation.¶
new_date_object = date_object_2026 + timedelta (days=14)
print(new_date_object)
new_date_string = new_date_object.strftime ("%d %B, %Y %Z")
print(new_date_string)2026-03-10 00:00:00+00:00
10 March, 2026 UTC
# Enter your code here:Click to reveal only AFTER you have tried your own code!
# Start with a string:
newDateStr = "2030 UTC 10 March 2026"
# Create datetime object from string; make it time-zone aware in the same line:
newDateObj = datetime.strptime(newDateStr, "%H%M UTC %d %B %Y").replace(tzinfo=tz_utc)
newDateObj