Lesson 12 - Working with Dates, Times, and Timezones
On this page
- Introduction
- Basic Date and Time Objects
- Formatting Dates and Times
- Parsing Date Strings
- Time Deltas: Working with Durations
- Working with Timezones
- Practical Example: Book Order System with Timestamps
- Comparing and Sorting Dates
- Working with Weekdays
- Comprehensive Example: Book Analytics Dashboard
- Summary
- Congratulations!
Introduction
Working with dates and times is essential for many applications—from recording when a book was published to tracking order timestamps to scheduling tasks. Python’s datetime module provides powerful tools for handling dates, times, and time intervals.
In this lesson, we’ll learn:
- Creating date and time objects
- Formatting dates and times for display
- Parsing date strings
- Working with time deltas (intervals)
- Timezone-aware datetime objects
- Practical examples for real-world applications
Basic Date and Time Objects
Python’s datetime module provides several classes:
datetime: Date and time togetherdate: Date only (year, month, day)time: Time only (hour, minute, second, microsecond)timedelta: Duration or difference between dates/times
Creating Date Objects
from datetime import date, datetime
# Current date
today = date.today()
print(f"Today: {today}") # 2025-11-11
# Specific date
book_published = date(2019, 7, 23)
print(f"Book published: {book_published}") # 2019-07-23
# Access components
print(f"Year: {book_published.year}")
print(f"Month: {book_published.month}")
print(f"Day: {book_published.day}")Creating DateTime Objects
from datetime import datetime
# Current date and time
now = datetime.now()
print(f"Now: {now}") # 2025-11-11 14:30:45.123456
# Specific datetime
order_time = datetime(2024, 11, 11, 14, 30, 0)
print(f"Order placed: {order_time}") # 2024-11-11 14:30:00
# Today at midnight
today_midnight = datetime.today().replace(hour=0, minute=0, second=0, microsecond=0)
print(f"Today at midnight: {today_midnight}")Formatting Dates and Times
Use strftime() (string format time) to format dates as strings:
from datetime import datetime
now = datetime.now()
# Common formats
print(now.strftime("%Y-%m-%d")) # 2025-11-11
print(now.strftime("%d/%m/%Y")) # 11/11/2025
print(now.strftime("%B %d, %Y")) # November 11, 2025
print(now.strftime("%A, %B %d, %Y")) # Tuesday, November 11, 2025
print(now.strftime("%I:%M %p")) # 02:30 PM
print(now.strftime("%Y-%m-%d %H:%M:%S")) # 2025-11-11 14:30:45Common format codes:
%Y- 4-digit year (2025)%m- 2-digit month (01-12)%d- 2-digit day (01-31)%H- Hour 24-hour (00-23)%I- Hour 12-hour (01-12)%M- Minute (00-59)%S- Second (00-59)%p- AM/PM%A- Full weekday name%B- Full month name
Practical Example: Book Publication Dates
from datetime import datetime
books = [
{'title': 'Python Crash Course', 'published': datetime(2019, 7, 23)},
{'title': 'Automate the Boring Stuff', 'published': datetime(2020, 1, 15)},
{'title': 'Learning Python', 'published': datetime(2013, 6, 12)},
]
print("Book Publication Dates:")
for book in books:
formatted = book['published'].strftime("%B %d, %Y")
print(f" '{book['title']}' - Published: {formatted}")Output:
Book Publication Dates:
'Python Crash Course' - Published: July 23, 2019
'Automate the Boring Stuff' - Published: January 15, 2020
'Learning Python' - Published: June 12, 2013Parsing Date Strings
Use strptime() (string parse time) to parse strings into datetime objects:
from datetime import datetime
# Parse various date formats
date_strings = [
("2024-11-11", "%Y-%m-%d"),
("11/11/2024", "%m/%d/%Y"),
("November 11, 2024", "%B %d, %Y"),
("11-Nov-2024 14:30:00", "%d-%b-%Y %H:%M:%S"),
]
for date_str, format_str in date_strings:
parsed = datetime.strptime(date_str, format_str)
print(f"{date_str:25} → {parsed}")Output:
2024-11-11 → 2024-11-11 00:00:00
11/11/2024 → 2024-11-11 00:00:00
November 11, 2024 → 2024-11-11 00:00:00
11-Nov-2024 14:30:00 → 2024-11-11 14:30:00Practical Example: Processing Order Data
from datetime import datetime
order_data = [
"2024-11-10 09:15:30,Python Basics,29.99",
"2024-11-10 14:22:45,Python Advanced,49.99",
"2024-11-11 10:05:12,Data Science 101,39.99",
]
orders = []
for line in order_data:
timestamp_str, title, price = line.split(',')
timestamp = datetime.strptime(timestamp_str, "%Y-%m-%d %H:%M:%S")
orders.append({
'timestamp': timestamp,
'title': title,
'price': float(price)
})
# Display orders
print("Orders:")
for order in orders:
time_formatted = order['timestamp'].strftime("%b %d at %I:%M %p")
print(f" {time_formatted}: {order['title']} (${order['price']})")Output:
Orders:
Nov 10 at 09:15 AM: Python Basics ($29.99)
Nov 10 at 02:22 PM: Python Advanced ($49.99)
Nov 11 at 10:05 AM: Data Science 101 ($39.99)Time Deltas: Working with Durations
timedelta represents a duration—the difference between two dates/times:
from datetime import datetime, timedelta
now = datetime.now()
# Create timedeltas
one_day = timedelta(days=1)
one_week = timedelta(weeks=1)
one_hour = timedelta(hours=1)
two_days_three_hours = timedelta(days=2, hours=3, minutes=30)
# Add/subtract timedeltas
tomorrow = now + one_day
yesterday = now - one_day
next_week = now + one_week
print(f"Now: {now.strftime('%Y-%m-%d %H:%M')}")
print(f"Tomorrow: {tomorrow.strftime('%Y-%m-%d %H:%M')}")
print(f"Yesterday: {yesterday.strftime('%Y-%m-%d %H:%M')}")
print(f"Next week: {next_week.strftime('%Y-%m-%d %H:%M')}")Calculating Differences
from datetime import datetime
book_published = datetime(2019, 7, 23)
now = datetime.now()
age = now - book_published
print(f"Book was published {age.days} days ago")
print(f"That's approximately {age.days // 365} years")Practical Example: Subscription Expiration
from datetime import datetime, timedelta
class Subscription:
def __init__(self, user, start_date, duration_days=30):
self.user = user
self.start_date = start_date
self.end_date = start_date + timedelta(days=duration_days)
def is_active(self):
return datetime.now() < self.end_date
def days_remaining(self):
remaining = self.end_date - datetime.now()
return max(0, remaining.days)
def display_status(self):
if self.is_active():
days = self.days_remaining()
print(f"{self.user}: Active ({days} days remaining)")
print(f" Expires: {self.end_date.strftime('%B %d, %Y')}")
else:
print(f"{self.user}: Expired")
print(f" Expired on: {self.end_date.strftime('%B %d, %Y')}")
# Create subscriptions
sub1 = Subscription("Alice", datetime.now() - timedelta(days=5), duration_days=30)
sub2 = Subscription("Bob", datetime.now() - timedelta(days=35), duration_days=30)
sub1.display_status()
print()
sub2.display_status()Output:
Alice: Active (25 days remaining)
Expires: December 06, 2025
Bob: Expired
Expired on: October 07, 2025Working with Timezones
By default, datetime objects are “naive” (no timezone info). For timezone-aware datetimes, use pytz or Python 3.9+ zoneinfo:
from datetime import datetime
from zoneinfo import ZoneInfo
# Create timezone-aware datetime
utc_now = datetime.now(ZoneInfo("UTC"))
eastern = datetime.now(ZoneInfo("America/New_York"))
tokyo = datetime.now(ZoneInfo("Asia/Tokyo"))
print(f"UTC: {utc_now.strftime('%Y-%m-%d %H:%M:%S %Z')}")
print(f"Eastern: {eastern.strftime('%Y-%m-%d %H:%M:%S %Z')}")
print(f"Tokyo: {tokyo.strftime('%Y-%m-%d %H:%M:%S %Z')}")Converting Between Timezones
from datetime import datetime
from zoneinfo import ZoneInfo
# Create a datetime in one timezone
eastern_time = datetime(2024, 11, 11, 14, 30, tzinfo=ZoneInfo("America/New_York"))
# Convert to other timezones
utc_time = eastern_time.astimezone(ZoneInfo("UTC"))
tokyo_time = eastern_time.astimezone(ZoneInfo("Asia/Tokyo"))
print(f"Eastern: {eastern_time.strftime('%I:%M %p %Z')}")
print(f"UTC: {utc_time.strftime('%I:%M %p %Z')}")
print(f"Tokyo: {tokyo_time.strftime('%I:%M %p %Z')}")Practical Example: Book Order System with Timestamps
from datetime import datetime, timedelta
from zoneinfo import ZoneInfo
class BookOrder:
def __init__(self, order_id, book_title, customer, timezone="UTC"):
self.order_id = order_id
self.book_title = book_title
self.customer = customer
self.timezone = ZoneInfo(timezone)
self.order_time = datetime.now(self.timezone)
self.estimated_delivery = self.order_time + timedelta(days=5)
def display_order(self):
print(f"\nOrder #{self.order_id}")
print(f" Book: {self.book_title}")
print(f" Customer: {self.customer}")
print(f" Ordered: {self.order_time.strftime('%B %d, %Y at %I:%M %p %Z')}")
print(f" Est. Delivery: {self.estimated_delivery.strftime('%B %d, %Y')}")
def time_since_order(self):
now = datetime.now(self.timezone)
elapsed = now - self.order_time
hours = elapsed.total_seconds() / 3600
if hours < 1:
minutes = elapsed.total_seconds() / 60
return f"{int(minutes)} minutes ago"
elif hours < 24:
return f"{int(hours)} hours ago"
else:
return f"{elapsed.days} days ago"
# Create orders in different timezones
order1 = BookOrder(1001, "Python Crash Course", "Alice", "America/New_York")
order2 = BookOrder(1002, "Data Science 101", "Bob", "Europe/London")
order3 = BookOrder(1003, "Machine Learning", "Charlie", "Asia/Tokyo")
for order in [order1, order2, order3]:
order.display_order()
print(f" Placed: {order.time_since_order()}")Comparing and Sorting Dates
from datetime import datetime
books = [
{'title': 'Python Crash Course', 'published': datetime(2019, 7, 23)},
{'title': 'Automate the Boring Stuff', 'published': datetime(2020, 1, 15)},
{'title': 'Learning Python', 'published': datetime(2013, 6, 12)},
{'title': 'Data Science Handbook', 'published': datetime(2016, 11, 25)},
]
# Sort by publication date (oldest first)
sorted_books = sorted(books, key=lambda x: x['published'])
print("Books by publication date (oldest first):")
for book in sorted_books:
pub_date = book['published'].strftime("%B %Y")
print(f" {pub_date}: {book['title']}")
# Find most recent book
newest = max(books, key=lambda x: x['published'])
print(f"\nNewest book: {newest['title']} ({newest['published'].year})")
# Filter books from last 5 years
five_years_ago = datetime.now() - timedelta(days=365*5)
recent_books = [b for b in books if b['published'] > five_years_ago]
print(f"\nBooks from last 5 years:")
for book in recent_books:
print(f" {book['title']} ({book['published'].year})")Output:
Books by publication date (oldest first):
June 2013: Learning Python
November 2016: Data Science Handbook
July 2019: Python Crash Course
January 2020: Automate the Boring Stuff
Newest book: Automate the Boring Stuff (2020)
Books from last 5 years:
Python Crash Course (2019)
Automate the Boring Stuff (2020)Working with Weekdays
from datetime import datetime, timedelta
def next_business_day(start_date):
"""Get next business day (Monday-Friday)"""
next_day = start_date + timedelta(days=1)
# If weekend (5=Saturday, 6=Sunday), skip to Monday
while next_day.weekday() >= 5:
next_day += timedelta(days=1)
return next_day
# Test it
today = datetime.now()
next_bd = next_business_day(today)
print(f"Today: {today.strftime('%A, %B %d')}")
print(f"Next business day: {next_bd.strftime('%A, %B %d')}")
# Count business days in a range
def count_business_days(start_date, end_date):
"""Count business days between two dates"""
count = 0
current = start_date
while current <= end_date:
if current.weekday() < 5: # Monday-Friday
count += 1
current += timedelta(days=1)
return count
start = datetime(2024, 11, 1)
end = datetime(2024, 11, 30)
biz_days = count_business_days(start, end)
print(f"\nBusiness days in November 2024: {biz_days}")Comprehensive Example: Book Analytics Dashboard
from datetime import datetime, timedelta
from collections import Counter
# Sample sales data with timestamps
sales_data = [
("2024-11-01 10:30:00", "Python Basics", 29.99),
("2024-11-01 14:15:00", "Python Advanced", 49.99),
("2024-11-02 09:45:00", "Python Basics", 29.99),
("2024-11-02 16:20:00", "Data Science 101", 39.99),
("2024-11-03 11:10:00", "Python Basics", 29.99),
("2024-11-05 13:30:00", "Machine Learning", 59.99),
("2024-11-05 15:45:00", "Python Advanced", 49.99),
("2024-11-06 10:00:00", "Data Science 101", 39.99),
]
# Parse sales data
sales = []
for timestamp_str, title, price in sales_data:
timestamp = datetime.strptime(timestamp_str, "%Y-%m-%d %H:%M:%S")
sales.append({
'timestamp': timestamp,
'title': title,
'price': price
})
# Analytics
print("=== BOOK SALES ANALYTICS ===\n")
# 1. Total sales
total_revenue = sum(sale['price'] for sale in sales)
print(f"Total Revenue: ${total_revenue:.2f}")
print(f"Total Transactions: {len(sales)}\n")
# 2. Sales by day
sales_by_day = {}
for sale in sales:
day = sale['timestamp'].date()
sales_by_day[day] = sales_by_day.get(day, 0) + sale['price']
print("Sales by Day:")
for day in sorted(sales_by_day.keys()):
revenue = sales_by_day[day]
day_name = datetime.combine(day, datetime.min.time()).strftime("%A, %B %d")
print(f" {day_name}: ${revenue:.2f}")
# 3. Peak sales time
sales_by_hour = Counter(sale['timestamp'].hour for sale in sales)
peak_hour = sales_by_hour.most_common(1)[0][0]
print(f"\nPeak Sales Hour: {peak_hour}:00 - {peak_hour+1}:00")
# 4. Best-selling book
book_sales = Counter(sale['title'] for sale in sales)
best_seller = book_sales.most_common(1)[0]
print(f"Best Seller: {best_seller[0]} ({best_seller[1]} copies)")
# 5. Time since last sale
last_sale = max(sales, key=lambda x: x['timestamp'])
now = datetime.now()
time_since = now - last_sale['timestamp']
print(f"\nLast Sale: {last_sale['title']}")
print(f" Time: {last_sale['timestamp'].strftime('%B %d at %I:%M %p')}")
print(f" ({time_since.days} days, {time_since.seconds // 3600} hours ago)")Output:
=== BOOK SALES ANALYTICS ===
Total Revenue: $328.92
Total Transactions: 8
Sales by Day:
Friday, November 01: $79.98
Saturday, November 02: $69.98
Sunday, November 03: $29.99
Tuesday, November 05: $109.98
Wednesday, November 06: $39.99
Peak Sales Hour: 10:00 - 11:00
Best Seller: Python Basics (3 copies)
Last Sale: Data Science 101
Time: November 06 at 10:00 AM
(5 days, 4 hours ago)Summary
In this lesson, we learned how to work with dates and times in Python:
dateanddatetimeobjects for representing dates and timesstrftime()for formatting dates as stringsstrptime()for parsing strings into datetime objectstimedeltafor representing durations and calculating differences- Timezone-aware datetimes using
zoneinfo - Comparing, sorting, and filtering by dates
- Working with weekdays and business days
Common use cases:
- Recording timestamps
- Formatting dates for display
- Parsing dates from various sources
- Calculating durations and deadlines
- Timezone conversions
- Filtering data by date ranges
- Scheduling and calendar operations
Best practices:
- Use timezone-aware datetimes for applications with users in multiple timezones
- Store datetimes in UTC, convert to local timezone for display
- Use ISO format (
YYYY-MM-DD) for consistency - Be careful with date arithmetic (months have different lengths)
- Consider using libraries like
python-dateutilfor complex date parsing
Congratulations!
You’ve completed the Python Advanced module! You now have a solid foundation in:
- Object-oriented programming (classes, inheritance, polymorphism)
- Advanced function concepts (closures, decorators, type hints)
- Iterators and generators
- Context managers
- Regular expressions
- Advanced collections
- Date and time handling
These skills will help you write more sophisticated, efficient, and maintainable Python code. Keep practicing and building projects to reinforce what you’ve learned!