Home› Tutorials› Standard Library
Standard Librarydatetime in Python: Dates, Times, Arithmetic, and Timezones
dateholds year/month/day;datetimeadds hour, minute, second, microsecond.- Subtract two
datetimeobjects to get atimedelta; add atimedeltato shift a date. strftime(format)converts to a string;strptime(string, format)parses back to adatetime.- Prefer
datetime.now(tz=timezone.utc)over naive datetimes when working across timezones.
date, time, and datetime
The datetime module exports three main classes for representing points in time:
date— stores year, month, and day. No time-of-day information.time— stores hour, minute, second, and microsecond. No calendar date.datetime— combines both: year, month, day, hour, minute, second, microsecond, and optional timezone info (tzinfo).
A fourth class, timedelta, represents a duration — the result of subtracting two dates or datetimes, or a duration you construct to add or subtract from a date.
All four are imported from the same module:
from datetime import date, time, datetime, timedelta, timezone
Creating instances
Follow these steps to create datetime objects:
- Specify values directly. Pass year, month, and day (and optionally time components) as positional arguments:
d = date(2026, 7, 1) # July 1, 2026 t = time(14, 30, 0) # 14:30:00 dt = datetime(2026, 7, 1, 14, 30, 0) - Use class methods for common values.
date.today()anddatetime.now()give the current date/time:today = date.today() now = datetime.now() - Build from a Unix timestamp.
datetime.fromtimestamp(ts)converts a POSIX timestamp to local time;datetime.utcfromtimestamp(ts)gives UTC (but returns a naive object — preferdatetime.fromtimestamp(ts, tz=timezone.utc)instead):import time as time_module ts = time_module.time() dt_utc = datetime.fromtimestamp(ts, tz=timezone.utc) - Combine a date and a time object.
d = date(2026, 7, 1) t = time(9, 0) dt = datetime.combine(d, t)
Date and time arithmetic with timedelta
Subtract two date or datetime objects to get a timedelta. Add or subtract a timedelta to shift a date:
from datetime import date, timedelta
start = date(2026, 1, 1)
end = date(2026, 7, 1)
gap = end - start
print(gap.days) # 181
two_weeks = timedelta(weeks=2)
deadline = end + two_weeks
print(deadline) # 2026-07-15
timedelta stores its value internally as days and seconds. Access them via .days, .seconds, and .microseconds. For the total duration in seconds, use .total_seconds():
d = timedelta(hours=36, minutes=30)
print(d.total_seconds()) # 131400.0
Formatting with strftime()
Call .strftime(format_string) on any date, time, or datetime object to produce a formatted string:
from datetime import datetime
dt = datetime(2026, 7, 1, 14, 30, 5)
print(dt.strftime("%Y-%m-%d")) # 2026-07-01
print(dt.strftime("%d %B %Y")) # 01 July 2026
print(dt.strftime("%I:%M %p")) # 02:30 PM
print(dt.strftime("%A, %d %b %Y")) # Wednesday, 01 Jul 2026
| Code | Meaning | Example |
|---|---|---|
%Y | 4-digit year | 2026 |
%m | Zero-padded month (01–12) | 07 |
%d | Zero-padded day (01–31) | 01 |
%B | Full month name | July |
%b | Abbreviated month name | Jul |
%A | Full weekday name | Wednesday |
%H | Hour in 24 h format (00–23) | 14 |
%I | Hour in 12 h format (01–12) | 02 |
%M | Minutes (00–59) | 30 |
%S | Seconds (00–59) | 05 |
%p | AM or PM | PM |
%Z | Timezone name | UTC |
Parsing strings with strptime()
datetime.strptime(string, format) is the inverse of strftime. It parses a string into a datetime object using the same format codes:
from datetime import datetime
s = "01 July 2026 14:30"
dt = datetime.strptime(s, "%d %B %Y %H:%M")
print(dt.year, dt.month, dt.day) # 2026 7 1
If the format does not match, Python raises ValueError. Wrap in a try/except block when parsing user-supplied strings:
try:
dt = datetime.strptime(user_input, "%Y-%m-%d")
except ValueError:
print("Invalid date format. Expected YYYY-MM-DD.")
Timezone-aware datetimes
tzinfo object. Mixing naive and aware datetimes in arithmetic raises TypeError. Always pick one convention and stick with it throughout your application.
The simplest way to work with UTC is to use the built-in timezone.utc constant:
from datetime import datetime, timezone
now_utc = datetime.now(tz=timezone.utc)
print(now_utc)
# 2026-07-01 14:30:05.123456+00:00
To work with other timezones, install the zoneinfo module (part of the standard library since Python 3.9) or the third-party pytz library:
from datetime import datetime
from zoneinfo import ZoneInfo
london = ZoneInfo("Europe/London")
tokyo = ZoneInfo("Asia/Tokyo")
now_london = datetime.now(tz=london)
now_tokyo = now_london.astimezone(tokyo)
print(now_tokyo) # same instant, different offset
date.today() vs datetime.now()
date.today() returns a date object (year, month, day only) using local time. datetime.now() returns a naive datetime in local time. datetime.now(tz=timezone.utc) returns an aware datetime in UTC.
For logging, API timestamps, and any situation where two machines in different timezones might compare values, always use the UTC-aware form. For simple date arithmetic where only calendar dates matter (age calculation, day-of-week lookup), date.today() is perfectly appropriate.
from datetime import date, datetime, timezone
print(date.today()) # 2026-07-01
print(datetime.now()) # 2026-07-01 14:30:05.123456 (naive)
print(datetime.now(tz=timezone.utc)) # 2026-07-01 14:30:05.123456+00:00 (aware)