Handling dates and times correctly is tricky. Here's how to do it in Python.
Basic Types
from datetime import date, time, datetime, timedelta
# Date (year, month, day)
d = date(2026, 3, 21)
d = date.today()
# Time (hour, minute, second, microsecond)
t = time(14, 30, 0)
# Datetime (date + time)
dt = datetime(2026, 3, 21, 14, 30, 0)
dt = datetime.now()
# Timedelta (duration)
delta = timedelta(days=7, hours=3)Current Date/Time
from datetime import datetime, date
# Current
datetime.now() # Local datetime
date.today() # Local date
# UTC
datetime.utcnow() # Deprecated in 3.12
datetime.now(timezone.utc) # PreferredCreating Datetimes
from datetime import datetime
# From components
dt = datetime(2026, 3, 21, 14, 30, 0)
# From timestamp
dt = datetime.fromtimestamp(1711036200)
# From string (ISO format)
dt = datetime.fromisoformat("2026-03-21T14:30:00")
# From string (custom format)
dt = datetime.strptime("21/03/2026 14:30", "%d/%m/%Y %H:%M")Formatting
dt = datetime(2026, 3, 21, 14, 30)
# ISO format
dt.isoformat() # "2026-03-21T14:30:00"
# Custom format
dt.strftime("%Y-%m-%d") # "2026-03-21"
dt.strftime("%B %d, %Y") # "March 21, 2026"
dt.strftime("%I:%M %p") # "02:30 PM"
dt.strftime("%A, %B %d") # "Saturday, March 21"Format Codes
| Code | Meaning | Example |
|---|---|---|
%Y | Year (4 digits) | 2026 |
%m | Month (01-12) | 03 |
%d | Day (01-31) | 21 |
%H | Hour 24h (00-23) | 14 |
%I | Hour 12h (01-12) | 02 |
%M | Minute (00-59) | 30 |
%S | Second (00-59) | 00 |
%p | AM/PM | PM |
%A | Weekday name | Saturday |
%B | Month name | March |
%z | UTC offset | +0000 |
Arithmetic
from datetime import datetime, timedelta
now = datetime.now()
# Add/subtract time
tomorrow = now + timedelta(days=1)
last_week = now - timedelta(weeks=1)
later = now + timedelta(hours=3, minutes=30)
# Difference between datetimes
dt1 = datetime(2026, 3, 21)
dt2 = datetime(2026, 4, 1)
diff = dt2 - dt1 # timedelta(days=11)
diff.days # 11
diff.total_seconds() # 950400.0Comparing
dt1 = datetime(2026, 3, 21)
dt2 = datetime(2026, 4, 1)
dt1 < dt2 # True
dt1 == dt2 # False
dt1 != dt2 # True
# Check if in range
start = datetime(2026, 1, 1)
end = datetime(2026, 12, 31)
start <= dt1 <= end # TrueTimezones
from datetime import datetime, timezone, timedelta
# UTC
utc_now = datetime.now(timezone.utc)
# Custom offset
eastern = timezone(timedelta(hours=-5))
dt = datetime.now(eastern)
# Using zoneinfo (Python 3.9+)
from zoneinfo import ZoneInfo
eastern = ZoneInfo("America/New_York")
pacific = ZoneInfo("America/Los_Angeles")
dt = datetime.now(eastern)
dt_pacific = dt.astimezone(pacific)Timezone Best Practices
from datetime import datetime, timezone
# Always store in UTC
utc_time = datetime.now(timezone.utc)
# Convert to local for display
from zoneinfo import ZoneInfo
local_tz = ZoneInfo("America/New_York")
local_time = utc_time.astimezone(local_tz)Components
dt = datetime(2026, 3, 21, 14, 30, 45)
dt.year # 2026
dt.month # 3
dt.day # 21
dt.hour # 14
dt.minute # 30
dt.second # 45
dt.weekday() # 5 (Saturday, 0=Monday)
dt.date() # date(2026, 3, 21)
dt.time() # time(14, 30, 45)Replace Components
dt = datetime(2026, 3, 21, 14, 30)
# Create new datetime with changed values
dt.replace(year=2027) # 2027-03-21 14:30
dt.replace(hour=0, minute=0) # 2026-03-21 00:00Common Patterns
Start/end of day
def start_of_day(dt):
return dt.replace(hour=0, minute=0, second=0, microsecond=0)
def end_of_day(dt):
return dt.replace(hour=23, minute=59, second=59, microsecond=999999)Date range
def date_range(start, end):
current = start
while current <= end:
yield current
current += timedelta(days=1)
for d in date_range(date(2026, 3, 1), date(2026, 3, 7)):
print(d)Age calculation
def calculate_age(birthdate):
today = date.today()
age = today.year - birthdate.year
if (today.month, today.day) < (birthdate.month, birthdate.day):
age -= 1
return ageHuman-readable relative time
def time_ago(dt):
diff = datetime.now() - dt
seconds = diff.total_seconds()
if seconds < 60:
return "just now"
if seconds < 3600:
return f"{int(seconds // 60)} minutes ago"
if seconds < 86400:
return f"{int(seconds // 3600)} hours ago"
return f"{diff.days} days ago"Quick Reference
from datetime import datetime, date, time, timedelta, timezone
# Create
datetime.now()
datetime(2026, 3, 21, 14, 30)
datetime.fromisoformat("2026-03-21T14:30:00")
datetime.strptime(string, format)
# Format
dt.isoformat()
dt.strftime(format)
# Arithmetic
dt + timedelta(days=1)
dt2 - dt1 # Returns timedelta
# Components
dt.year, dt.month, dt.day
dt.hour, dt.minute, dt.second
dt.date(), dt.time()
# Timezone
datetime.now(timezone.utc)
dt.astimezone(new_tz)Always use timezone-aware datetimes in production. Store UTC, display local.
React to this post: