Datetime
Source
src/basic/datetime_.py
Introduction
Learn More
For more examples and detailed explanations, see the Real Python guide on introduction.
Python's datetime module provides classes for manipulating dates and times. The module includes date for calendar dates, time for clock times, datetime for combined date and time, timedelta for durations, and timezone for UTC offsets. Python 3.9+ also includes zoneinfo for IANA timezone support. Understanding these classes is essential for logging, scheduling, data analysis, and any application that works with temporal data.
Current Date and Time
Learn More
For more examples and detailed explanations, see the Real Python guide on current date and time.
Getting the current date and time is one of the most common operations. Use datetime.now() for local time or datetime.utcnow() for UTC. In Python 3.11+, prefer datetime.now(timezone.utc) over utcnow() which is deprecated.
from datetime import datetime, date, time, timezone
# Current local datetime
now = datetime.now()
print(now) # 2024-01-15 10:30:45.123456
# Current UTC datetime (Python 3.11+ preferred)
utc_now = datetime.now(timezone.utc)
print(utc_now) # 2024-01-15 02:30:45.123456+00:00
# Current date only
today = date.today()
print(today) # 2024-01-15
# Current time only
current_time = datetime.now().time()
print(current_time) # 10:30:45.123456Creating Datetime Objects
Learn More
For more examples and detailed explanations, see the Real Python guide on creating datetime objects.
You can create datetime objects by specifying year, month, day, and optionally hour, minute, second, and microsecond. The date and time classes work similarly for date-only or time-only values.
from datetime import datetime, date, time
# Create specific datetime
dt = datetime(2024, 1, 15, 10, 30, 45)
print(dt) # 2024-01-15 10:30:45
# Create date only
d = date(2024, 1, 15)
print(d) # 2024-01-15
# Create time only
t = time(10, 30, 45)
print(t) # 10:30:45
# Combine date and time
combined = datetime.combine(d, t)
print(combined) # 2024-01-15 10:30:45
# Get date or time from datetime
print(dt.date()) # 2024-01-15
print(dt.time()) # 10:30:45Timestamps
Learn More
For more examples and detailed explanations, see the Real Python guide on timestamps.
Unix timestamps represent seconds since January 1, 1970 (the Unix epoch). Converting between timestamps and datetime objects is common when working with APIs, databases, and log files.
import time
from datetime import datetime, timezone
# Current timestamp
ts = time.time()
print(ts) # 1705312245.123456
# Timestamp to datetime (local time)
dt = datetime.fromtimestamp(ts)
print(dt) # 2024-01-15 10:30:45.123456
# Timestamp to datetime (UTC)
dt_utc = datetime.fromtimestamp(ts, tz=timezone.utc)
print(dt_utc) # 2024-01-15 02:30:45.123456+00:00
# Datetime to timestamp
ts_back = dt.timestamp()
print(ts_back) # 1705312245.123456
# Millisecond timestamp (common in JavaScript/APIs)
ts_ms = int(ts * 1000)
print(ts_ms) # 1705312245123Formatting Dates (strftime)
Learn More
For more examples and detailed explanations, see the Real Python guide on formatting dates strftime.
The strftime() method formats datetime objects as strings using format codes. This is essential for displaying dates to users, generating filenames, or formatting data for APIs.
from datetime import datetime
dt = datetime(2024, 1, 15, 14, 30, 45)
# Common formats
print(dt.strftime("%Y-%m-%d")) # 2024-01-15
print(dt.strftime("%d/%m/%Y")) # 15/01/2024
print(dt.strftime("%B %d, %Y")) # January 15, 2024
print(dt.strftime("%Y-%m-%d %H:%M:%S")) # 2024-01-15 14:30:45
print(dt.strftime("%I:%M %p")) # 02:30 PM
print(dt.strftime("%A, %B %d")) # Monday, January 15
# ISO 8601 format
print(dt.isoformat()) # 2024-01-15T14:30:45
# For filenames (no special characters)
print(dt.strftime("%Y%m%d_%H%M%S")) # 20240115_143045Common format codes:
%Y- 4-digit year (2024)%m- Month as zero-padded number (01-12)%d- Day as zero-padded number (01-31)%H- Hour 24-hour format (00-23)%I- Hour 12-hour format (01-12)%M- Minute (00-59)%S- Second (00-59)%p- AM/PM%A- Full weekday name%B- Full month name%z- UTC offset (+0000)%Z- Timezone name
Parsing Dates (strptime)
Learn More
For more examples and detailed explanations, see the Real Python guide on parsing dates strptime.
The strptime() method parses strings into datetime objects. The format string must match the input exactly. This is commonly used when reading dates from files, user input, or APIs.
from datetime import datetime
# Parse various formats
dt1 = datetime.strptime("2024-01-15", "%Y-%m-%d")
dt2 = datetime.strptime("15/01/2024", "%d/%m/%Y")
dt3 = datetime.strptime("January 15, 2024", "%B %d, %Y")
dt4 = datetime.strptime("2024-01-15 14:30:45", "%Y-%m-%d %H:%M:%S")
print(dt1) # 2024-01-15 00:00:00
print(dt4) # 2024-01-15 14:30:45
# Parse ISO 8601 format
dt5 = datetime.fromisoformat("2024-01-15T14:30:45")
print(dt5) # 2024-01-15 14:30:45
# Parse with timezone (Python 3.11+)
dt6 = datetime.fromisoformat("2024-01-15T14:30:45+00:00")
print(dt6) # 2024-01-15 14:30:45+00:00Date Arithmetic with timedelta
Learn More
For more examples and detailed explanations, see the Real Python guide on date arithmetic with timedelta.
The timedelta class represents a duration—the difference between two dates or times. Use it to add or subtract time from datetime objects, or to calculate the difference between two dates.
from datetime import datetime, timedelta
now = datetime.now()
# Add time
tomorrow = now + timedelta(days=1)
next_week = now + timedelta(weeks=1)
in_2_hours = now + timedelta(hours=2)
in_90_minutes = now + timedelta(minutes=90)
# Subtract time
yesterday = now - timedelta(days=1)
last_month = now - timedelta(days=30)
# Combine units
future = now + timedelta(days=5, hours=3, minutes=30)
# Calculate difference between dates
date1 = datetime(2024, 1, 1)
date2 = datetime(2024, 12, 31)
diff = date2 - date1
print(diff.days) # 365
print(diff.total_seconds()) # 31536000.0
# Compare dates
print(date2 > date1) # TrueTimezones
Learn More
For more examples and detailed explanations, see the Real Python guide on timezones.
Working with timezones correctly is crucial for applications serving users across different regions. Python 3.9+ includes zoneinfo for IANA timezone support. For earlier versions, use pytz or dateutil.
from datetime import datetime, timezone, timedelta
# UTC timezone
utc = timezone.utc
dt_utc = datetime.now(utc)
print(dt_utc) # 2024-01-15 02:30:45.123456+00:00
# Fixed offset timezone
pst = timezone(timedelta(hours=-8))
dt_pst = datetime.now(pst)
print(dt_pst) # 2024-01-14 18:30:45.123456-08:00
# Convert between timezones
dt_converted = dt_utc.astimezone(pst)
print(dt_converted)
# Python 3.9+ with zoneinfo
from zoneinfo import ZoneInfo
eastern = ZoneInfo("America/New_York")
tokyo = ZoneInfo("Asia/Tokyo")
dt_eastern = datetime.now(eastern)
dt_tokyo = dt_eastern.astimezone(tokyo)
print(dt_tokyo)
# Make naive datetime timezone-aware
naive = datetime(2024, 1, 15, 10, 30)
aware = naive.replace(tzinfo=utc)Comparing Dates
Learn More
For more examples and detailed explanations, see the Real Python guide on comparing dates.
Datetime objects support comparison operators. When comparing timezone-aware and naive datetimes, Python raises a TypeError to prevent subtle bugs.
from datetime import datetime, date, timedelta
dt1 = datetime(2024, 1, 15, 10, 0)
dt2 = datetime(2024, 1, 15, 14, 0)
dt3 = datetime(2024, 1, 16, 10, 0)
# Comparisons
print(dt1 < dt2) # True
print(dt1 == dt2) # False
print(dt3 > dt2) # True
# Check if date is in range
start = datetime(2024, 1, 1)
end = datetime(2024, 12, 31)
check = datetime(2024, 6, 15)
print(start <= check <= end) # True
# Check if date is today
today = date.today()
some_date = date(2024, 1, 15)
print(some_date == today)
# Days until a date
future = date(2024, 12, 25)
days_until = (future - today).days
print(f"Days until: {days_until}")Working with Weeks
Learn More
For more examples and detailed explanations, see the Real Python guide on working with weeks.
Getting week numbers, weekdays, and working with ISO week dates is common for reporting and scheduling applications.
from datetime import datetime, date, timedelta
dt = datetime(2024, 1, 15)
# Day of week (0=Monday, 6=Sunday)
print(dt.weekday()) # 0 (Monday)
print(dt.isoweekday()) # 1 (Monday, ISO format 1-7)
# Week number
print(dt.isocalendar()) # (2024, 3, 1) - year, week, weekday
# Get start of week (Monday)
start_of_week = dt - timedelta(days=dt.weekday())
print(start_of_week) # 2024-01-15 00:00:00
# Get end of week (Sunday)
end_of_week = start_of_week + timedelta(days=6)
print(end_of_week) # 2024-01-21 00:00:00
# Check if weekend
is_weekend = dt.weekday() >= 5
print(is_weekend) # FalseStart and End of Day/Month/Year
Learn More
For more examples and detailed explanations, see the Real Python guide on start and end of day month year.
Getting the start or end of a time period is useful for date range queries and reporting.
from datetime import datetime, date, time, timedelta
import calendar
dt = datetime(2024, 1, 15, 14, 30, 45)
# Start of day
start_of_day = datetime.combine(dt.date(), time.min)
print(start_of_day) # 2024-01-15 00:00:00
# End of day
end_of_day = datetime.combine(dt.date(), time.max)
print(end_of_day) # 2024-01-15 23:59:59.999999
# Start of month
start_of_month = dt.replace(day=1, hour=0, minute=0, second=0, microsecond=0)
print(start_of_month) # 2024-01-01 00:00:00
# End of month
last_day = calendar.monthrange(dt.year, dt.month)[1]
end_of_month = dt.replace(day=last_day, hour=23, minute=59, second=59)
print(end_of_month) # 2024-01-31 23:59:59
# Start of year
start_of_year = dt.replace(month=1, day=1, hour=0, minute=0, second=0, microsecond=0)
print(start_of_year) # 2024-01-01 00:00:00Calendar Operations
Learn More
For more examples and detailed explanations, see the Real Python guide on calendar operations.
The calendar module provides functions for working with calendars, including checking leap years, getting month ranges, and generating calendar displays.
import calendar
from datetime import date
# Check leap year
print(calendar.isleap(2024)) # True
print(calendar.isleap(2023)) # False
# Days in month
print(calendar.monthrange(2024, 2)) # (3, 29) - weekday of 1st, days in month
days_in_feb = calendar.monthrange(2024, 2)[1]
print(days_in_feb) # 29
# Generate month calendar
print(calendar.month(2024, 1))
# Iterate through month days
cal = calendar.Calendar()
for day in cal.itermonthdays(2024, 1):
if day != 0:
print(day, end=" ") # 1 2 3 ... 31Date Ranges
Learn More
For more examples and detailed explanations, see the Real Python guide on date ranges.
Generating sequences of dates is useful for reports, charts, and scheduling.
from datetime import datetime, date, timedelta
def date_range(start, end, step=timedelta(days=1)):
"""Generate dates from start to end."""
current = start
while current <= end:
yield current
current += step
# Daily dates
start = date(2024, 1, 1)
end = date(2024, 1, 7)
for d in date_range(start, end):
print(d)
# Weekly dates
for d in date_range(start, date(2024, 1, 31), timedelta(weeks=1)):
print(d)
# Business days (skip weekends)
def business_days(start, end):
current = start
while current <= end:
if current.weekday() < 5: # Monday=0 to Friday=4
yield current
current += timedelta(days=1)Age Calculation
Learn More
For more examples and detailed explanations, see the Real Python guide on age calculation.
Calculating age from a birthdate requires handling the edge case where the birthday hasn't occurred yet this year.
from datetime import date
def calculate_age(birthdate):
"""Calculate age in years from birthdate."""
today = date.today()
age = today.year - birthdate.year
# Subtract 1 if birthday hasn't occurred this year
if (today.month, today.day) < (birthdate.month, birthdate.day):
age -= 1
return age
birthdate = date(1990, 6, 15)
age = calculate_age(birthdate)
print(f"Age: {age}")
# Days until next birthday
def days_until_birthday(birthdate):
today = date.today()
next_birthday = birthdate.replace(year=today.year)
if next_birthday < today:
next_birthday = next_birthday.replace(year=today.year + 1)
return (next_birthday - today).daysHuman Readable Time Differences
Learn More
For more examples and detailed explanations, see the Real Python guide on human readable time differences.
Converting timedelta to human-readable strings like "2 hours ago" or "in 3 days" improves user experience.
from datetime import datetime, timedelta
def time_ago(dt):
"""Convert datetime to human-readable relative time."""
now = datetime.now()
diff = now - dt
seconds = diff.total_seconds()
if seconds < 60:
return "just now"
elif seconds < 3600:
minutes = int(seconds // 60)
return f"{minutes} minute{'s' if minutes != 1 else ''} ago"
elif seconds < 86400:
hours = int(seconds // 3600)
return f"{hours} hour{'s' if hours != 1 else ''} ago"
elif seconds < 604800:
days = int(seconds // 86400)
return f"{days} day{'s' if days != 1 else ''} ago"
else:
return dt.strftime("%B %d, %Y")
# Examples
print(time_ago(datetime.now() - timedelta(minutes=5))) # 5 minutes ago
print(time_ago(datetime.now() - timedelta(hours=2))) # 2 hours ago
print(time_ago(datetime.now() - timedelta(days=3))) # 3 days agoUsing dateutil for Flexible Parsing
Learn More
For more examples and detailed explanations, see the Real Python guide on python dateutil parser.
The python-dateutil library provides powerful parsing that handles many date formats automatically, plus relative delta calculations.
# pip install python-dateutil
from dateutil import parser
from dateutil.relativedelta import relativedelta
from datetime import datetime
# Flexible parsing - handles many formats automatically
dt1 = parser.parse("January 15, 2024")
dt2 = parser.parse("15/01/2024")
dt3 = parser.parse("2024-01-15T14:30:45Z")
dt4 = parser.parse("Jan 15 2024 2:30 PM")
# Relative delta - handles months and years correctly
now = datetime.now()
# Add 1 month (handles varying month lengths)
next_month = now + relativedelta(months=1)
# Add 1 year
next_year = now + relativedelta(years=1)
# Last day of next month
last_of_next_month = now + relativedelta(months=1, day=31)
# Complex relative: 2 months and 3 days ago
past = now - relativedelta(months=2, days=3)