Working with dates and times is an essential skill in Python programming, especially for applications involving scheduling, logging events, or time-based calculations. While it might seem straightforward, managing dates and times can quickly become complex due to different formats, time zones, and daylight saving changes. This lesson introduces you to Python's datetime module—the powerful and versatile toolkit for handling date and time data.
By the end of this lesson, you will understand how to create, manipulate, and format dates and times, compare them, and perform arithmetic operations on them. Let's dive in!
Why Python's datetime Module?
Python's built-in datetime module offers classes for manipulating dates and times in both simple and complex ways. It supports:
- Representing dates, times, or both together
- Timezone-aware and naive datetime objects
- Parsing and formatting dates and times in human-readable strings
- Performing arithmetic operations like addition and subtraction
Before datetime, developers manually parsed strings or used less consistent methods, making date-time handling error-prone. With datetime, Python provides a standardized, reliable API.
Core Classes in datetime
The module contains several classes, but the key ones you'll use are:
date: Handles calendar dates (year, month, day)time: Handles time independent of any date (hour, minute, second, microsecond)datetime: Combines date and time into one objecttimedelta: Represents a duration, the difference between two dates or timestimezone: For handling timezone-aware datetime objects
Let's explore these classes practically.
Getting Started: Importing datetime
To access the module's features, import it as follows:
📌 Deep Dive: Importing datetime
import datetime
Alternatively, you can import specific classes for convenience:
📌 Deep Dive: Importing Specific Classes
from datetime import date, time, datetime, timedelta
Working with Dates
The date class represents a calendar date. You can create a date object by specifying the year, month, and day.
📌 Deep Dive: Creating and Using date Objects
from datetime import date
# Create a date object for July 4, 2024
independence_day = date(2024, 7, 4)
print(independence_day) # 2024-07-04
print(independence_day.year) # 2024
print(independence_day.month) # 7
print(independence_day.day) # 4
# Get today's date
today = date.today()
print(today)
Note: The date.today() method returns the current local date.
Working with Times
The time class allows you to represent a specific time independent of any date. It supports hour, minute, second, microsecond, and timezone info.
📌 Deep Dive: Creating and Using time Objects
from datetime import time
# Create a time object for 2:30:45 PM
afternoon = time(14, 30, 45)
print(afternoon) # 14:30:45
print(afternoon.hour) # 14
print(afternoon.minute) # 30
print(afternoon.second) # 45
print(afternoon.microsecond) # 0 (default)
The datetime Class: Combining Date & Time
The datetime class is the most commonly used class because it combines a date and a time into one object. This is useful for timestamps, event logging, or any context where date and time go hand-in-hand.
📌 Deep Dive: Creating and Using datetime Objects
from datetime import datetime
# Create a datetime object for January 1, 2023 at 12:00 noon
new_year = datetime(2023, 1, 1, 12, 0, 0)
print(new_year) # 2023-01-01 12:00:00
print(new_year.year) # 2023
print(new_year.month) # 1
print(new_year.day) # 1
print(new_year.hour) # 12
print(new_year.minute) # 0
print(new_year.second) # 0
# Get the current date and time
now = datetime.now()
print(now)
Formatting Dates and Times: strftime and strptime
Often, you need to convert dates and times to strings in a readable or specific format or parse strings into datetime objects. The strftime method converts datetime objects to strings, and strptime parses strings into datetime objects.
📌 Deep Dive: Formatting and Parsing Dates
from datetime import datetime
now = datetime.now()
# Format datetime to string
formatted = now.strftime("%A, %B %d, %Y at %I:%M %p")
print("Formatted date:", formatted)
# Parse string back to datetime
date_string = "21 June, 2024 15:30"
parsed_date = datetime.strptime(date_string, "%d %B, %Y %H:%M")
print("Parsed datetime:", parsed_date)
Here are some common formatting directives for strftime and strptime:
| Directive | Description |
|---|---|
| %Y | Year with century (e.g., 2024) |
| %m | Month as zero-padded decimal (01-12) |
| %d | Day of the month (01-31) |
| %H | Hour (24-hour clock) (00-23) |
| %I | Hour (12-hour clock) (01-12) |
| %M | Minute (00-59) |
| %S | Second (00-59) |
| %p | AM or PM |
| %A | Full weekday name (e.g., Monday) |
| %B | Full month name (e.g., January) |
Performing Date and Time Arithmetic with timedelta
The timedelta class represents a duration or difference between two dates or times. You can add or subtract timedeltas to manipulate date or datetime objects.
📌 Deep Dive: Using timedelta for Date Arithmetic
from datetime import datetime, timedelta
# Current datetime
now = datetime.now()
# 10 days from now
ten_days_later = now + timedelta(days=10)
print("10 days later:", ten_days_later)
# 3 hours ago
three_hours_ago = now - timedelta(hours=3)
print("3 hours ago:", three_hours_ago)
# Difference between two dates
new_year = datetime(2025, 1, 1)
diff = new_year - now
print(f"Days until New Year 2025: {diff.days}")
print(f"Seconds until New Year 2025: {diff.total_seconds():.0f}")
Time Zones and Aware vs Naive Objects
By default, datetime objects are "naive" — they do not contain timezone information. This is usually fine for many applications, but when working across time zones or with UTC, you need "aware" datetime objects.
Python's datetime.timezone class helps you create timezone-aware datetime objects.
📌 Deep Dive: Creating Timezone-Aware Datetimes
from datetime import datetime, timezone, timedelta
# UTC timezone
utc_now = datetime.now(timezone.utc)
print("Current UTC time:", utc_now)
# Create timezone for UTC+2 hours
utc_plus_two = timezone(timedelta(hours=2))
# Local time with UTC+2 offset
local_time = datetime.now(utc_plus_two)
print("Local time (UTC+2):", local_time)
💡 Timezone Tips
Handling time zones can be tricky. For comprehensive timezone support (including daylight saving time), consider using third-party libraries like pytz or Python 3.9+'s zoneinfo module.
Comparing Dates and Times
Python allows direct comparison of date, time, and datetime objects using the usual comparison operators (<, <=, >, >=, ==, !=).
📌 Deep Dive: Comparing Dates and Times
from datetime import date
d1 = date(2024, 6, 15)
d2 = date(2024, 12, 25)
if d1 < d2:
print("d1 is earlier than d2")
else:
print("d1 is the same or later than d2")
Note that comparing naive and aware datetime objects will raise an error. Always ensure consistency when comparing.
Parsing Dates from User Input
When accepting dates from users (command line input, files, APIs), the input will often be strings. Use datetime.strptime() to safely parse these strings into datetime objects.
📌 Deep Dive: Parsing User Input
from datetime import datetime
user_input = "2024-06-15 14:45:00"
try:
user_date = datetime.strptime(user_input, "%Y-%m-%d %H:%M:%S")
print("Parsed datetime:", user_date)
except ValueError:
print("Invalid date format. Please use YYYY-MM-DD HH:MM:SS")
Common Pitfalls and Tips
- Beware of naive vs aware datetime: Mixing timezone-aware and naive datetimes in comparisons or arithmetic causes errors.
- Use UTC internally: For apps involving multiple time zones, store and operate in UTC, then convert for display.
- Always validate user input: Use try-except blocks around
strptimeto handle unexpected formats gracefully. - Remember that months and days are one-indexed: January is month 1, not 0.

Summary
Handling dates and times in Python is straightforward once you understand the datetime module's classes and methods. You can:
- Create date, time, and combined datetime objects
- Get the current date and time
- Format dates and times into readable strings and parse strings back
- Do arithmetic with date/time differences using
timedelta - Work with time zones and create timezone-aware datetime objects
- Compare dates and times using comparison operators
With these skills, you can confidently build robust, time-aware applications.
💡 Next Steps
Explore modules like calendar for advanced calendar operations, or third-party libraries such as dateutil and pytz for enhanced timezone and parsing capabilities.
Quick Knowledge Check
Test what you just learned
Question 1 of 2
Which class from the datetime module would you use to represent a calendar date without time?
Question 2 of 2
What method would you use to convert a datetime object into a formatted string?
Loading results...