python/cpython · error · TypeError

fromutc() requires a datetime argument

Error message

fromutc() requires a datetime argument

What it means

Raised by tzinfo.fromutc() when its argument is not a datetime instance. fromutc(dt) converts a datetime expressing UTC time into local time under this tzinfo; the default implementation reads dt.utcoffset(), dt.dst() and dt.tzinfo, so it requires a real datetime. Passing a date, a time, a timestamp number, or a string triggers this TypeError.

Source

Thrown at Lib/_pydatetime.py:1335

        raise NotImplementedError("tzinfo subclass must override tzname()")

    def utcoffset(self, dt):
        "datetime -> timedelta, positive for east of UTC, negative for west of UTC"
        raise NotImplementedError("tzinfo subclass must override utcoffset()")

    def dst(self, dt):
        """datetime -> DST offset as timedelta, positive for east of UTC.

        Return 0 if DST not in effect.  utcoffset() must include the DST
        offset.
        """
        raise NotImplementedError("tzinfo subclass must override dst()")

    def fromutc(self, dt):
        "datetime in UTC -> datetime in local time."

        if not isinstance(dt, datetime):
            raise TypeError("fromutc() requires a datetime argument")
        if dt.tzinfo is not self:
            raise ValueError("dt.tzinfo is not self")

        dtoff = dt.utcoffset()
        if dtoff is None:
            raise ValueError("fromutc() requires a non-None utcoffset() "
                             "result")

        # See the long comment block at the end of this file for an
        # explanation of this algorithm.
        dtdst = dt.dst()
        if dtdst is None:
            raise ValueError("fromutc() requires a non-None dst() result")
        delta = dtoff - dtdst
        if delta:
            dt += delta
            dtdst = dt.dst()
            if dtdst is None:

View on GitHub (pinned to bc6749cc3b)

Solutions

  1. Parse the value to a datetime first: datetime.fromisoformat(s) before calling fromutc
  2. If you have a POSIX timestamp, use datetime.fromtimestamp(ts, tz) — it applies fromutc internally
  3. Ensure the datetime is UTC-based and has tzinfo set to this tzinfo object before calling

Example fix

// before
local = tz.fromutc('2024-06-01T12:00:00+00:00')

// after
from datetime import datetime, timezone
dt_utc = datetime.fromisoformat('2024-06-01T12:00:00+00:00').replace(tzinfo=tz)
local = tz.fromutc(dt_utc)
Defensive patterns

Strategy: type-guard

Validate before calling

if not isinstance(dt, datetime):
    if isinstance(dt, str):
        dt = datetime.fromisoformat(dt)
    elif isinstance(dt, (int, float)):
        dt = datetime.fromtimestamp(dt, timezone.utc)
    else:
        raise TypeError('fromutc needs a datetime')
tz.fromutc(dt)

Type guard

from datetime import datetime as _dt
def is_datetime(v) -> bool:
    return isinstance(v, _dt)

Try / catch

try:
    local = tz.fromutc(dt)
except TypeError:
    local = tz.fromutc(datetime.fromisoformat(dt))  # after confirming the input type

Prevention

When it happens

Trigger: tz.fromutc(time(12,0)); tz.fromutc('2024-01-01T00:00:00'); tz.fromutc(date(2024,1,1)); tz.fromutc(1700000000); passing a pandas Timestamp subclass that fails isinstance in exotic cases.

Common situations: Wrapping fromutc in generic conversion utilities that accept multiple input types; confusing fromutc with datetime.fromtimestamp (which takes a number); feeding ISO strings directly instead of parsing them first.

Related errors


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