Lesson 20 — Date and Time
Working with Dates
Python's datetime module handles dates, times, timedeltas, and timezone-aware computation. It is essential for financial, HR, and scheduling applications.
PYTHON — Basics
from datetime import date, datetime, timedelta
import calendar
# Today and now:
today = date.today() # date only: 2025-04-01
now = datetime.now() # date and time: 2025-04-01 14:30:00
print(today)
print(now)
print(f"Year: {now.year}, Month: {now.month}, Day: {now.day}")
print(f"Hour: {now.hour}, Minute: {now.minute}")
PYTHON — Formatting and parsing
# Formatting — strftime:
print(now.strftime("%A, %d %B %Y")) # Tuesday, 01 April 2025
print(now.strftime("%Y-%m-%d")) # 2025-04-01
print(now.strftime("%d/%m/%Y %H:%M")) # 01/04/2025 14:30
# Parsing a string — strptime:
date_str = "15/03/1999"
parsed = datetime.strptime(date_str, "%d/%m/%Y").date()
print(parsed) # 1999-03-15
print(type(parsed)) # <class 'datetime.date'>
# ISO format:
print(today.isoformat()) # 2025-04-01
birth = date.fromisoformat("1999-03-15")
PYTHON — timedelta
# timedelta — representing durations:
from datetime import timedelta
one_week = timedelta(weeks=1)
thirty_days = timedelta(days=30)
deadline = today + thirty_days
print(f"Deadline: {deadline}")
days_until = (deadline - today).days
print(f"Days until deadline: {days_until}")
# Age in years:
birth_date = date(1999, 3, 15)
today_date = date.today()
age = today_date.year - birth_date.year
if (today_date.month, today_date.day) < (birth_date.month, birth_date.day):
age -= 1
print(f"Age: {age}")
# Days until end of year:
end_of_year = date(today.year, 12, 31)
days_remaining = (end_of_year - today).days
print(f"Days remaining in {today.year}: {days_remaining}")
Timezone-Aware Datetime
PYTHON — Timezones
from datetime import timezone
from zoneinfo import ZoneInfo # Python 3.9+
# UTC:
now_utc = datetime.now(timezone.utc)
print(now_utc)
# South Africa Standard Time (SAST = UTC+2, no daylight saving):
sast = ZoneInfo("Africa/Johannesburg")
now_sast = datetime.now(sast)
print(f"SAST: {now_sast.strftime("%Y-%m-%d %H:%M %Z")}")
Practice Task
Your Turn
Write a function learner_report(name, birth_date_str, enrol_date_str, mark) that: parses both date strings (format dd/mm/yyyy), calculates the learner's age, calculates days since enrolment, calculates days until their next birthday, and returns a formatted report string. Test with three learners.
Common Mistakes
- Mixing date and datetime objects in arithmetic — they are different types.
- Wrong strftime/strptime codes: %m is month (01-12), %M is minutes. %d is day, %D is locale date.
- Timezone-naive and timezone-aware datetime cannot be compared or subtracted.
- Birthday comparison for age — months and days must be compared as a tuple, not separately.
Professional Tip
Always store datetimes as UTC in your database and convert to local time only for display. This prevents a whole class of bugs when systems operate across time zones.
Mini Quiz
Which class represents a duration between two datetimes?
timedelta represents a duration. Add it to or subtract it from a date or datetime to compute new dates.