|$ curl https://forge-ai.dev/api/markdown?path=docs/python/datetime-time
$cat docs/datetime-&-time.md
updated Today·18-24 min read·published

datetime & Time

PythondatetimezoneinfoIntermediate🎯Free Tools
Introduction

Prefer timezone-aware datetimes. The modern stdlib stack is datetime + zoneinfo (IANA tz database). Avoid naive datetimes in production systems.

datetime Basics
dt_basics.py
Python
1from datetime import datetime, date, time, timedelta, timezone
2
3now = datetime.now(timezone.utc)
4print(now.isoformat())
5print(date.today(), time(12, 30))
6print(datetime(2026, 7, 30, 12, 0, tzinfo=timezone.utc))
7
8delta = timedelta(days=1, hours=2, minutes=30)
9print(now + delta)
10print((now - delta).timestamp())
zoneinfo
zoneinfo_demo.py
Python
1from datetime import datetime, timezone
2from zoneinfo import ZoneInfo
3
4utc = datetime.now(timezone.utc)
5ny = utc.astimezone(ZoneInfo("America/New_York"))
6tokyo = utc.astimezone(ZoneInfo("Asia/Tokyo"))
7print(ny.isoformat(), tokyo.isoformat())
8
9# construct in a zone
10meeting = datetime(2026, 11, 1, 9, 0, tzinfo=ZoneInfo("America/New_York"))
11print(meeting.astimezone(timezone.utc))
📝

note

On some Windows installs you may need the tzdata package: pip install tzdata.
Parsing & Formatting
parse.py
Python
1from datetime import datetime, timezone
2
3s = "2026-07-30T12:00:00+00:00"
4dt = datetime.fromisoformat(s)
5print(dt)
6
7# strptime / strftime
8raw = "30/07/2026 12:00"
9dt2 = datetime.strptime(raw, "%d/%m/%Y %H:%M").replace(tzinfo=timezone.utc)
10print(dt2.strftime("%Y-%m-%dT%H:%M:%SZ"))
Comparisons & Arithmetic
compare.py
Python
1from datetime import datetime, timezone, timedelta
2from zoneinfo import ZoneInfo
3
4a = datetime(2026, 1, 1, tzinfo=timezone.utc)
5b = datetime(2026, 1, 1, tzinfo=ZoneInfo("America/New_York"))
6# Aware datetimes compare correctly across zones:
7print(a > b)
8print(a - b)
9
10# Mixing naive and aware raises TypeError
11# datetime.now() - a # TypeError

danger

Never compare naive and aware datetimes. Store UTC; convert for display.
DST Edge Cases
dst.py
Python
1from datetime import datetime
2from zoneinfo import ZoneInfo
3
4tz = ZoneInfo("America/New_York")
5# fold attribute distinguishes ambiguous wall times
6ambiguous = datetime(2026, 11, 1, 1, 30, tzinfo=tz, fold=0)
7ambiguous2 = datetime(2026, 11, 1, 1, 30, tzinfo=tz, fold=1)
8print(ambiguous.astimezone(), ambiguous2.astimezone())
pendulum (mention)

Third-party pendulum offers nicer ergonomics (duration math, parsing). Prefer stdlib zoneinfo unless you need pendulum's extras.

pendulum_demo.py
Python
1# pip install pendulum
2# import pendulum
3# dt = pendulum.now("Europe/Paris")
4# print(dt.add(days=1).to_iso8601_string())
timedelta Patterns
td.py
Python
1from datetime import timedelta
2
3def humanize(td: timedelta) -> str:
4 secs = int(td.total_seconds())
5 sign = "-" if secs < 0 else ""
6 secs = abs(secs)
7 h, rem = divmod(secs, 3600)
8 m, s = divmod(rem, 60)
9 return f"{sign}{h:02d}:{m:02d}:{s:02d}"
10
11print(humanize(timedelta(hours=2, minutes=5, seconds=1)))
12print(timedelta(weeks=1).total_seconds())
Storage Recommendations
LayerRecommendation
DatabaseTIMESTAMPTZ / UTC instant
JSON APIsISO 8601 with offset or Z
LogsUTC ISO
UIConvert with zoneinfo per user tz
Naive datetimeAvoid except date-only domains
date & time Objects
date_time.py
Python
1from datetime import date, time, datetime, timezone
2
3d = date(2026, 7, 30)
4t = time(14, 30, tzinfo=timezone.utc)
5print(d.isoformat(), t.isoformat())
6print(datetime.combine(d, t))
7print(d.toordinal(), date.fromordinal(d.toordinal()))
8print(d.weekday()) # Monday=0
calendar Module
calendar_mod.py
Python
1import calendar
2print(calendar.month(2026, 7))
3print(calendar.isleap(2024))
4print(calendar.monthrange(2026, 2)) # weekday of first day, days in month
time Module (clocks)
time_mod.py
Python
1import time
2
3t0 = time.perf_counter()
4time.sleep(0.01)
5print(time.perf_counter() - t0)
6
7print(time.time()) # wall clock epoch seconds
8print(time.monotonic()) # non-decreasing clock for durations

best practice

Use time.perf_counter/monotonic for measuring durations; datetime for civil time.
With Pydantic
pyd_dt.py
Python
1from datetime import datetime
2from pydantic import BaseModel
3
4class Event(BaseModel):
5 starts_at: datetime
6
7e = Event.model_validate({"starts_at": "2026-07-30T12:00:00Z"})
8print(e.starts_at, e.starts_at.tzinfo)
Pitfalls
  • datetime.now() without tz → naive
  • utcnow() is deprecated — use now(timezone.utc)
  • Localize with pytz .localize carefully — prefer zoneinfo
  • Storing local wall time without zone loses meaning
dateutil mention

For relative deltas like "next month", the third-party python-dateutil relativedelta is common. Stdlib timedelta cannot express calendar months.

dateutil_demo.py
Python
1# pip install python-dateutil
2# from dateutil.relativedelta import relativedelta
3# from datetime import datetime, timezone
4# print(datetime.now(timezone.utc) + relativedelta(months=+1))
FAQ
QuestionAnswer
Store UTC or local?UTC instant; convert for display
pytz or zoneinfo?zoneinfo (3.9+)
Measure latency?time.perf_counter
Parse Z suffix?fromisoformat handles +00:00; replace Z
parse_z.py
Python
1from datetime import datetime
2
3def parse_iso(s: str) -> datetime:
4 return datetime.fromisoformat(s.replace("Z", "+00:00"))
5
6print(parse_iso("2026-07-30T12:00:00Z"))
Summary

Always prefer aware datetimes with zoneinfo, store UTC, convert for display, and use perf_counter for measuring durations. Replace deprecated utcnow() with now(timezone.utc).

utcnow_fix.py
Python
1from datetime import datetime, timezone
2# BAD: datetime.utcnow() # naive
3# GOOD:
4print(datetime.now(timezone.utc))
Checklist
  • datetime.now(timezone.utc) for current instant
  • zoneinfo for named zones
  • ISO 8601 in APIs
  • No naive/aware mixing
  • perf_counter for benchmarks
  • tzdata installed on Windows if needed
ISO Calendar
iso.py
Python
1from datetime import date
2d = date(2026, 7, 30)
3print(d.isocalendar()) # year, week, weekday
4print(d.isoweekday()) # Monday=1
$Blueprint — Engineering Documentation·Section ID: PYTHON-DATETIME·Revision: 1.0

Community

Get help on Slack, Discord or VIP

Stuck on a guide? Join the community and ask.