Official Documentation & Resources
Primary Official Sources (REQUIRED)
- Python Official Library Documentation: https://docs.python.org/3/library/datetime.html#datetime-objects
- Python Official Tutorial: https://docs.python.org/3/tutorial/index.html
- Module Source Code: https://github.com/python/cpython/blob/main/Lib/datetime.py
Additional Authoritative Sources
- Real Python - Working with Dates and Times: https://realpython.com/python-datetime/
- GeeksforGeeks - Python DateTime: https://www.geeksforgeeks.org/python-datetime-module/
- Python Module of the Week (PyMOTW) - datetime: https://pymotw.com/3/datetime/
- Stack Overflow datetime questions: https://stackoverflow.com/questions/tagged/python+datetime
IMPORTANT: Examples in this guide are adapted from the official Python documentation at https://docs.python.org/3/library/datetime.html
Overview
The datetime class is a combination of a date and a time. It has all the attributes of both date and time objects, and can be timezone-aware or timezone-naive. This is the most commonly used class in the datetime module for representing specific moments in time.
A datetime object is a single object containing all the information from a date object and a time object.
Key Characteristics
- Combined Date and Time: Contains both date and time information
- Immutable Objects: Datetime objects cannot be modified after creation
- Thread Safety: Datetime objects are immutable and therefore thread-safe
- Timezone Support: Can be timezone-naive or timezone-aware
- Microsecond Precision: Supports microsecond precision (6 decimal places)
- Arithmetic Support: Supports addition/subtraction with timedelta objects
- Hashable: Can be used as dictionary keys and in sets
Prerequisites and Setup
Python Version Compatibility
- Minimum Python version required: Python 2.3+ (datetime module introduction)
- Timezone support: Python 3.2+ (timezone class)
- Enhanced timezone: Python 3.6+ (zoneinfo support)
Installation and Imports
# Standard library (no installation needed)
from datetime import datetime, timezone
# Alternative import
import datetime
# Then use: datetime.datetime()
Basic Usage
Official Documentation Examples
Source: All examples adapted from https://docs.python.org/3/library/datetime.html#datetime-objects
Simple Example
from datetime import datetime
# Current datetime (from official docs)
now = datetime.now()
print(f"Now: {now}") # Now: 2025-06-14 10:30:45.123456
# Creating specific datetime (from official docs)
dt = datetime(2025, 6, 14, 12, 30, 45)
print(f"Specific: {dt}") # Specific: 2025-06-14 12:30:45
# Datetime formatting (from official docs)
print(dt.strftime("%Y-%m-%d %H:%M:%S")) # 2025-06-14 12:30:45
Core Methods/Functions
from datetime import datetime, timezone
# Constructor (from official docs)
dt = datetime(2025, 6, 14, 12, 30, 45)
print(dt) # 2025-06-14 12:30:45
# Current time methods (from official docs)
now_local = datetime.now()
now_utc = datetime.now(timezone.utc)
print(f"Local: {now_local}")
print(f"UTC: {now_utc}")
# ISO format (from official docs)
iso_dt = dt.isoformat()
print(f"ISO format: {iso_dt}") # ISO format: 2025-06-14T12:30:45
Common Patterns
# Pattern 1: Basic usage (from official docs)
from datetime import datetime, timezone
dt = datetime(2025, 6, 14, 12, 30, 45, 123456)
print(f"Year: {dt.year}, Month: {dt.month}, Day: {dt.day}")
print(f"Hour: {dt.hour}, Minute: {dt.minute}, Second: {dt.second}")
# Pattern 2: Datetime parsing (from official docs)
iso_string = "2025-06-14T12:30:45"
parsed_dt = datetime.fromisoformat(iso_string)
print(f"Parsed: {parsed_dt}")
# Pattern 3: UTC handling (from official docs)
utc_now = datetime.now(timezone.utc)
local_now = datetime.now()
print(f"UTC: {utc_now}")
print(f"Local: {local_now}")
datetime API Reference
Constructor
| Method | Description | Parameters | Return Type | Example |
|---|---|---|---|---|
datetime(year, month, day, hour, minute, second, microsecond, tzinfo) | Create a datetime object | year, month, day required; others optional | datetime | datetime(2025, 6, 14, 12, 30) |
Class Methods
| Method | Description | Return Type | Example |
|---|---|---|---|
now(tz=None) | Current local datetime | datetime | datetime.now() |
utcnow() | Current UTC datetime (deprecated) | datetime | datetime.utcnow() |
today() | Current local datetime | datetime | datetime.today() |
fromisoformat(date_string) | Parse ISO 8601 string | datetime | datetime.fromisoformat('2025-06-14T12:30:00') |
fromtimestamp(timestamp, tz=None) | From Unix timestamp | datetime | datetime.fromtimestamp(1718373000) |
utcfromtimestamp(timestamp) | UTC datetime from timestamp (deprecated) | datetime | datetime.utcfromtimestamp(1718373000) |
fromordinal(ordinal) | From proleptic Gregorian ordinal | datetime | datetime.fromordinal(738000) |
combine(date, time, tzinfo=None) | Combine date and time objects | datetime | datetime.combine(date.today(), time(12, 30)) |
Instance Methods
| Method | Description | Return Type | Example |
|---|---|---|---|
strftime(format) | Format as string | str | dt.strftime('%Y-%m-%d %H:%M:%S') |
isoformat(sep='T', timespec='auto') | ISO 8601 format | str | dt.isoformat() |
date() | Date component | date | dt.date() |
time() | Time component | time | dt.time() |
timetz() | Time component with timezone | time | dt.timetz() |
timestamp() | Unix timestamp | float | dt.timestamp() |
replace(**kwargs) | Return datetime with new values | datetime | dt.replace(year=2026) |
timetuple() | time.struct_time object | struct_time | dt.timetuple() |
utctimetuple() | UTC time tuple | struct_time | dt.utctimetuple() |
toordinal() | Proleptic Gregorian ordinal | int | dt.toordinal() |
weekday() | Day of week (Monday=0) | int | dt.weekday() |
isoweekday() | Day of week (Monday=1) | int | dt.isoweekday() |
isocalendar() | ISO calendar tuple | tuple | dt.isocalendar() |
ctime() | String representing the datetime | str | dt.ctime() |
Timezone Methods (for timezone-aware objects)
| Method | Description | Return Type | Example |
|---|---|---|---|
utcoffset() | UTC offset | timedelta or None | dt.utcoffset() |
dst() | Daylight saving time offset | timedelta or None | dt.dst() |
tzname() | Timezone name | str or None | dt.tzname() |
astimezone(tz=None) | Convert to timezone | datetime | dt.astimezone(timezone.utc) |
Properties and Attributes
| Attribute | Description | Type | Range | Example |
|---|---|---|---|---|
year | Year | int | 1-9999 | dt.year |
month | Month | int | 1-12 | dt.month |
day | Day | int | 1-31 | dt.day |
hour | Hour | int | 0-23 | dt.hour |
minute | Minute | int | 0-59 | dt.minute |
second | Second | int | 0-59 | dt.second |
microsecond | Microsecond | int | 0-999999 | dt.microsecond |
tzinfo | Timezone info | tzinfo or None | - | dt.tzinfo |
Detailed Method Examples
Creating datetime Objects (from official docs)
from datetime import datetime, timezone, timedelta
# Basic creation (from official docs)
dt = datetime(2025, 6, 14, 12, 30, 45)
print(dt) # 2025-06-14 12:30:45
# With microseconds (from official docs)
precise = datetime(2025, 6, 14, 12, 30, 45, 123456)
print(precise) # 2025-06-14 12:30:45.123456
# With timezone (from official docs)
utc_dt = datetime(2025, 6, 14, 12, 30, 45, tzinfo=timezone.utc)
print(utc_dt) # 2025-06-14 12:30:45+00:00
# Current time (from official docs)
now = datetime.now()
utc_now = datetime.now(timezone.utc)
print(f"Local now: {now}")
print(f"UTC now: {utc_now}")
# From ISO format (from official docs)
iso_dt = datetime.fromisoformat('2025-06-14T12:30:45')
print(f"From ISO: {iso_dt}")
# From timestamp (from official docs)
timestamp_dt = datetime.fromtimestamp(1718373045)
print(f"From timestamp: {timestamp_dt}")
Datetime Formatting (from official docs)
from datetime import datetime
dt = datetime(2025, 6, 14, 12, 30, 45, 123456)
# ISO format (from official docs)
print(dt.isoformat()) # 2025-06-14T12:30:45.123456
# Different separators and timespec (from official docs)
print(dt.isoformat(' ')) # 2025-06-14 12:30:45.123456
print(dt.isoformat(timespec='seconds')) # 2025-06-14T12:30:45
print(dt.isoformat(timespec='minutes')) # 2025-06-14T12:30
# Custom formatting (from official docs)
print(dt.strftime("%Y-%m-%d %H:%M:%S")) # 2025-06-14 12:30:45
print(dt.strftime("%A, %B %d, %Y at %I:%M %p")) # Friday, June 14, 2025 at 12:30 PM
print(dt.strftime("%c")) # Fri Jun 14 12:30:45 2025
# Default string representation (from official docs)
print(dt.ctime()) # Fri Jun 14 12:30:45 2025
Datetime Arithmetic (from official docs)
from datetime import datetime, timedelta
dt = datetime(2025, 6, 14, 12, 30, 45)
# Adding/subtracting time (from official docs)
tomorrow = dt + timedelta(days=1)
print(f"Tomorrow: {tomorrow}") # Tomorrow: 2025-06-15 12:30:45
next_week = dt + timedelta(weeks=1)
print(f"Next week: {next_week}") # Next week: 2025-06-21 12:30:45
# Hours and minutes (from official docs)
later = dt + timedelta(hours=2, minutes=30)
print(f"Later: {later}") # Later: 2025-06-14 15:00:45
# Datetime difference (from official docs)
new_year = datetime(2025, 1, 1)
time_diff = dt - new_year
print(f"Days since New Year: {time_diff.days}") # Days since New Year: 164
print(f"Total seconds: {time_diff.total_seconds()}")
Component Extraction (from official docs)
from datetime import datetime
dt = datetime(2025, 6, 14, 12, 30, 45, 123456)
# Date and time components (from official docs)
date_part = dt.date()
time_part = dt.time()
print(f"Date: {date_part}") # Date: 2025-06-14
print(f"Time: {time_part}") # Time: 12:30:45.123456
# Individual properties (from official docs)
print(f"Year: {dt.year}") # Year: 2025
print(f"Month: {dt.month}") # Month: 6
print(f"Day: {dt.day}") # Day: 14
print(f"Hour: {dt.hour}") # Hour: 12
print(f"Minute: {dt.minute}") # Minute: 30
print(f"Second: {dt.second}") # Second: 45
print(f"Microsecond: {dt.microsecond}") # Microsecond: 123456
Timezone Operations (from official docs)
from datetime import datetime, timezone, timedelta
# UTC datetime (from official docs)
utc_dt = datetime.now(timezone.utc)
print(f"UTC: {utc_dt}")
# Custom timezone (from official docs)
est = timezone(timedelta(hours=-5))
est_dt = datetime.now(est)
print(f"EST: {est_dt}")
# Converting timezones (from official docs)
local_dt = datetime.now()
utc_converted = local_dt.replace(tzinfo=timezone.utc)
print(f"Converted to UTC: {utc_converted}")
# Timezone conversion (from official docs)
if utc_dt.tzinfo:
local_converted = utc_dt.astimezone()
print(f"Converted to local: {local_converted}")
Datetime Replacement (from official docs)
from datetime import datetime
dt = datetime(2025, 6, 14, 12, 30, 45)
# Replace date components (from official docs)
new_year = dt.replace(year=2026)
print(f"New year: {new_year}") # New year: 2026-06-14 12:30:45
# Replace time components (from official docs)
new_time = dt.replace(hour=18, minute=0, second=0)
print(f"New time: {new_time}") # New time: 2025-06-14 18:00:00
# Multiple replacements (from official docs)
new_dt = dt.replace(year=2024, month=12, day=31, hour=23, minute=59)
print(f"New datetime: {new_dt}") # New datetime: 2024-12-31 23:59:45
Timestamp Operations (from official docs)
from datetime import datetime, timezone
dt = datetime(2025, 6, 14, 12, 30, 45)
# Get timestamp (from official docs)
timestamp = dt.timestamp()
print(f"Timestamp: {timestamp}")
# Round trip (from official docs)
recreated = datetime.fromtimestamp(timestamp)
print(f"Recreated: {recreated}")
# UTC timestamp (from official docs)
utc_dt = datetime.now(timezone.utc)
utc_timestamp = utc_dt.timestamp()
print(f"UTC timestamp: {utc_timestamp}")
Important Notes
Gotchas and Common Pitfalls
- Datetime objects are immutable - methods return new objects
- Mixing timezone-naive and timezone-aware datetimes causes errors
utcnow()andutcfromtimestamp()are deprecated in Python 3.12+- Arithmetic operations require timedelta objects
- Timezone conversion requires proper timezone objects
Error Handling
from datetime import datetime
# Invalid datetime handling (from official docs)
try:
invalid = datetime(2025, 2, 30) # February doesn't have 30 days
except ValueError as e:
print(f"Error: {e}")
try:
invalid = datetime(2025, 6, 14, 25, 0, 0) # Hour out of range
except ValueError as e:
print(f"Error: {e}")
# Timezone comparison error
try:
naive_dt = datetime.now()
aware_dt = datetime.now(timezone.utc)
comparison = naive_dt < aware_dt # This will raise TypeError
except TypeError as e:
print(f"Error: {e}")
Performance Considerations
- Datetime objects are efficient for most use cases
- Timezone-aware operations require additional computation
- String formatting can be expensive for large datasets
- Use replace() instead of creating new objects when possible
Best Practices
- Always use timezone-aware datetimes - Use
datetime.now(timezone.utc)instead ofdatetime.utcnow() - Handle timezone conversions properly - Use
astimezone()for conversion - Use ISO format for serialization - Use
isoformat()for consistent formatting - Store times in UTC - Convert to local time only for display
- Handle ValueError exceptions - Invalid datetimes will raise ValueError
- Use replace() for modifications - Returns new object with specified changes
- Be consistent with timezone awareness - Don't mix naive and aware datetimes
Related Classes
- datetime.date - Date component without time
- datetime.time - Time component without date
- datetime.timedelta - Time duration for arithmetic
- datetime.timezone - Timezone information
- datetime.tzinfo - Abstract timezone base class
- Main datetime module - Complete module overview