python/cpython · error · TypeError

dst() argument must be a datetime instance or None

Error message

dst() argument must be a datetime instance or None

What it means

timezone.dst(dt) always returns None (fixed offsets have no daylight-saving component), but the dt argument must still be a datetime instance or None to satisfy the tzinfo protocol. Anything else raises TypeError before the constant is returned.

Source

Thrown at Lib/_pydatetime.py:2531

    def utcoffset(self, dt):
        if isinstance(dt, datetime) or dt is None:
            return self._offset
        raise TypeError("utcoffset() argument must be a datetime instance"
                        " or None")

    def tzname(self, dt):
        if isinstance(dt, datetime) or dt is None:
            if self._name is None:
                return self._name_from_offset(self._offset)
            return self._name
        raise TypeError("tzname() argument must be a datetime instance"
                        " or None")

    def dst(self, dt):
        if isinstance(dt, datetime) or dt is None:
            return None
        raise TypeError("dst() argument must be a datetime instance"
                        " or None")

    def fromutc(self, dt):
        if isinstance(dt, datetime):
            if dt.tzinfo is not self:
                raise ValueError("fromutc: dt.tzinfo "
                                 "is not self")
            return dt + self._offset
        raise TypeError("fromutc() argument must be a datetime instance"
                        " or None")

    _maxoffset = timedelta(hours=24, microseconds=-1)
    _minoffset = -_maxoffset

    @staticmethod
    def _name_from_offset(delta):
        if not delta:
            return 'UTC'

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Call with a datetime or None: tz.dst(None) returns None for fixed zones
  2. If checking a specific moment, use dt.dst() on the aware datetime itself
  3. Add isinstance guards in generic utilities that invoke tzinfo methods

Example fix

// before
in_dst = tz.dst(event_date) is not None  # event_date is date

# after
in_dst = tz.dst(datetime.combine(event_date, time())) is not None  # False for fixed zones
Defensive patterns

Strategy: type-guard

Validate before calling

from datetime import datetime

def in_dst(tz, dt) -> bool:
    probe = dt if isinstance(dt, datetime) or dt is None else None
    return tz.dst(probe) is not None

Type guard

from datetime import datetime

def is_datetime_or_none(v) -> bool:
    return v is None or isinstance(v, datetime)

Prevention

When it happens

Trigger: tz.dst(date.today()); tz.dst(0); generic DST-checking utilities forwarding non-datetime keys. Frequently hit by code that iterates objects and calls dst() on each without type discipline.

Common situations: DST detection helpers applied over mixed collections; passing timestamps as ints/strings; ported Java Joda-style code assuming per-instant objects.

Related errors


AI-assisted analysis of python/cpython@bc6749cc3b (2026-08-14). Data as JSON: /api/errors/c4ae787a98c38588. Report an issue: GitHub.