datetime.utcoffset / tzname / dst
The same three questions exist on datetime, time, timezone and tzinfo. On a datetime or time they simply forward to tzinfo — passing the datetime itself (or None for a time) — and return None when there is no tzinfo.
Common call
dt.utcoffset()
Returns
datetime.timedelta(seconds=7200) for +02:00; None if naive
Replaces
Parsing "+02:00" out of strings
Watch out
timezone.dst() is always None — fixed offsets know nothing of DST
dt.utcoffset() · dt.tzname() · dt.dst()
→ timedelta | str | None
Demo
Live evaluation
All three questions on one parsed timestamp.
Try:
Inputs
whenstran ISO 8601 timestamp
Code
from datetime import datetime dt = datetime.fromisoformat('2026-09-29T14:30+02:00') (dt.utcoffset(), dt.tzname(), dt.dst())
Result
(datetime.timedelta(seconds=7200), 'UTC+02:00', None)
Negative offsets are normalized timedeltas (-05:30 is days=-1, seconds=66600) but total_seconds() gives the plain signed value. Naive values return None for all three — and None.total_seconds() is an AttributeError, so check for None first.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| dt | datetime | None | yes | Only on timezone / tzinfo methods: the datetime being asked about. timezone accepts None or a datetime and ignores it. |
Return value
timedelta | str | None — utcoffset and dst: a timedelta or None. tzname: a str or None.
Attributes
| Attribute | Type | Meaning |
|---|---|---|
| utcoffset() | timedelta | None | Local time minus UTC, DST included: +02:00 → timedelta(seconds=7200), -05:00 → timedelta(days=-1, seconds=68400). |
| tzname() | str | None | timezone: its name, or "UTC±HH:MM" generated from the offset ("UTC" for zero). zoneinfo: abbreviations like "CEST". |
| dst() | timedelta | None | How much of the offset is daylight saving. None for timezone objects and naive values. |
Common patterns
Offset as "+HH:MM" text
strftime %:z (3.12+) or isoformat already contain it.
label = dt.strftime('%:z') # '+02:00'
Offset in minutes, None-safe
Guard naive values.
off = dt.utcoffset() minutes = None if off is None else off // timedelta(minutes=1)
Is daylight saving in effect?
Only meaningful with a DST-aware tzinfo such as zoneinfo.
in_dst = bool(dt.dst())
Examples
1. An aware datetime
from datetime import datetime, timedelta, timezone
dt = datetime(2026, 9, 29, 14, 30, tzinfo=timezone(timedelta(hours=2)))
(dt.utcoffset(), dt.tzname(), dt.dst())
Returns
(datetime.timedelta(seconds=7200), 'UTC+02:00', None)2. A naive datetime
from datetime import datetime
dt = datetime(2026, 9, 29)
(dt.utcoffset(), dt.tzname(), dt.dst())
Returns
(None, None, None)3. On a time
from datetime import time, timedelta, timezone
t = time(14, tzinfo=timezone(timedelta(hours=-3), 'BRT'))
(t.utcoffset(), t.tzname())
Returns
(datetime.timedelta(days=-1, seconds=75600), 'BRT')4. On the timezone itself
from datetime import UTC
(UTC.utcoffset(None), UTC.tzname(None), UTC.dst(None))
Returns
(datetime.timedelta(0), 'UTC', None)5. The dt argument is required
from datetime import timedelta, timezone
timezone(timedelta(hours=1)).utcoffset()
Returns
TypeError: timezone.utcoffset() takes exactly one argument (0 given)6. The abstract base
from datetime import tzinfo
tzinfo().tzname(None)
Returns
NotImplementedError: a tzinfo subclass must implement tzname()Pitfalls
1. Calling total_seconds() on a naive offset
Naive datetimes return None, which has no methods.
naive
from datetime import datetime datetime(2026, 9, 29).utcoffset().total_seconds()
AttributeError: 'NoneType' object has no attribute 'total_seconds'
check first
from datetime import datetime off = datetime(2026, 9, 29).utcoffset() 0.0 if off is None else off.total_seconds()
0.0
2. Passing an int to timezone.utcoffset
The argument is the datetime being asked about (or None), not an hour.
utcoffset(5)
from datetime import timedelta, timezone timezone(timedelta(hours=1)).utcoffset(5)
TypeError: utcoffset(dt) argument must be a datetime instance or None, not int
utcoffset(None)
from datetime import timedelta, timezone timezone(timedelta(hours=1)).utcoffset(None)
datetime.timedelta(seconds=3600)
When to use
Use it
- Finding out whether and how a value is zoned
- Displaying or storing the offset separately
Reach for something else
- Converting between zones → astimezone
- Deciding DST with a fixed offset — timezone.dst() is always None
Notes
CPython impl
datetime/time methods call tzinfo.utcoffset(self) (a time passes None) and validate the result: None or a timedelta strictly within ±24 h
Naive
No tzinfo → all three return None
timezone
utcoffset → the fixed offset, dst → None, tzname → the name or "UTC±HH:MM[:SS[.ffffff]]"
FAQ
dt.utcoffset() returns a timedelta (None if naive). For hours: dt.utcoffset().total_seconds() / 3600; for text: dt.strftime("%z") or "%:z".