datetime — Dates, Timezones & Durations
Intermediatedatetime + timedelta do date arithmetic; strftime/strptime convert to and from strings; and timezone-aware UTC datetimes are the only correct choice for backends.
Overview
Every backend logs, schedules, and expires things — all datetime work. The objects: date, time, datetime, timedelta (a duration). The two directions: strftime formats a datetime INTO a string, strptime parses a string INTO a datetime (mnemonic: f = format, p = parse). The production rule that separates juniors from engineers: store and compute in UTC with timezone-aware objects (datetime.now(timezone.utc), never naive utcnow()), convert to IST only at display time.
Arithmetic with timedelta
Subtracting datetimes yields a timedelta; adding a timedelta shifts time. Great for deadlines, expiry, and "days until" features.
from datetime import datetime, timedelta, date
now = datetime.now()
placement_day = datetime(2026, 12, 1, 9, 0)
gap = placement_day - now # timedelta
print(gap.days, "days left")
token_expiry = now + timedelta(hours=12)
print(now < token_expiry) # True
# Date-only math
today = date.today()
last_monday = today - timedelta(days=today.weekday())
print("week started:", last_monday)
# timedelta knows seconds too
print(timedelta(days=1).total_seconds()) # 86400.0
# Compare timestamps naturally
t1 = datetime(2026, 7, 10, 14, 30)
t2 = datetime(2026, 7, 10, 18, 0)
print(max(t1, t2)) # later oneParsing, Formatting & UTC Discipline
strptime needs the exact format of the input; strftime writes any format you want. For APIs, prefer ISO-8601 (isoformat/fromisoformat). Always attach a timezone in server code.
from datetime import datetime, timezone, timedelta
# String -> datetime (p = parse)
s = "10/07/2026 18:30"
dt = datetime.strptime(s, "%d/%m/%Y %H:%M")
# datetime -> string (f = format)
print(dt.strftime("%d %b %Y, %I:%M %p")) # 10 Jul 2026, 06:30 PM
# ISO-8601 — the API standard
print(dt.isoformat()) # 2026-07-10T18:30:00
back = datetime.fromisoformat("2026-07-10T18:30:00+05:30")
# PRODUCTION RULE: aware UTC, convert at the edge
utc_now = datetime.now(timezone.utc) # aware — has tzinfo
IST = timezone(timedelta(hours=5, minutes=30))
print(utc_now.astimezone(IST).strftime("%H:%M IST"))
# naive vs aware cannot be compared:
# datetime.now() < utc_now -> TypeError!
# and datetime.utcnow() is deprecated — it returns a NAIVE time.Key Points to Remember
- 1datetime - datetime = timedelta; datetime + timedelta = datetime
- 2strptime parses strings in, strftime formats out; ISO-8601 via isoformat()
- 3Store/compute in aware UTC — datetime.now(timezone.utc); convert to IST only for display
- 4Naive and aware datetimes cannot be compared — pick aware, everywhere
Interview Questions
Sign in to ask AriaHow do you compute the number of days between two dates?
Naive vs timezone-aware datetimes — why do backends standardize on aware UTC?
Ask Aria about datetime — Dates, Timezones & Durations
Your personal AI tutor — ask anything about this concept
Revision Status
Personal Notes
Sign in to save personal notes for this topic.
Discussion
Sign in to join the discussion.