{"record":{"id":"f8e4dcdcfae46166","repo":"pandas-dev/pandas","slug":"datetimeindex-has-mixed-timezones","errorCode":null,"errorMessage":"DatetimeIndex has mixed timezones","messagePattern":"DatetimeIndex has mixed timezones","errorType":"exception","errorClass":"TypeError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/datetimes.py","lineNumber":2862,"sourceCode":"        yearfirst=yearfirst,\n        creso=abbrev_to_npy_unit(out_unit),\n    )\n\n    if tz_parsed is not None:\n        # We can take a shortcut since the datetime64 numpy array\n        #  is in UTC\n        return result, tz_parsed\n    elif result.dtype.kind == \"M\":\n        return result, tz_parsed\n    elif result.dtype == object:\n        # GH#23675 when called via `pd.to_datetime`, returning an object-dtype\n        #  array is allowed.  When called via `pd.DatetimeIndex`, we can\n        #  only accept datetime64 dtype, so raise TypeError if object-dtype\n        #  is returned, as that indicates the values can be recognized as\n        #  datetimes but they have conflicting timezones/awareness\n        if allow_object:\n            return result, tz_parsed\n        raise TypeError(\"DatetimeIndex has mixed timezones\")\n    else:  # pragma: no cover\n        # GH#23675 this TypeError should never be hit, whereas the TypeError\n        #  in the object-dtype branch above is reachable.\n        raise TypeError(result)\n\n\ndef maybe_convert_dtype(data, copy: bool, tz: tzinfo | None = None):\n    \"\"\"\n    Convert data based on dtype conventions, issuing\n    errors where appropriate.\n\n    Parameters\n    ----------\n    data : np.ndarray or pd.Index\n    copy : bool\n    tz : tzinfo or None, default None\n\n    Returns","sourceCodeStart":2844,"sourceCodeEnd":2880,"githubUrl":"https://github.com/pandas-dev/pandas/blob/71959b8cb9b2459c16e14b34f28b178ccfe14735/pandas/core/arrays/datetimes.py#L2844-L2880","documentation":"Raised when constructing a DatetimeIndex from object-dtype data whose elements resolve to datetimes but disagree on tz (some aware, some naive, or multiple tzs). pandas cannot pick one tz, so when allow_object is False (the DatetimeIndex path) it refuses. TypeError.","triggerScenarios":"pd.DatetimeIndex([...]) where the list mixes aware and naive Timestamps/datetime.datetime; pd.to_datetime on a Series of Python datetimes that include some with tzinfo and some without.","commonSituations":"Concatenating data from sources with inconsistent tz handling; JSON/DB rows where some rows carry tz and others don't; user input mixed with default datetime.now().","solutions":["Normalize all elements to one tz before constructing, e.g. localize naive ones and tz_convert the rest to UTC.","Split aware vs naive rows, localize/convert separately, then concatenate.","At ingestion, enforce utc=True in pd.to_datetime so everything becomes UTC consistently."],"exampleFix":"# before\npd.DatetimeIndex([pd.Timestamp('2020', tz='UTC'), pd.Timestamp('2021')])\n# after\npd.DatetimeIndex([pd.Timestamp('2020', tz='UTC'), pd.Timestamp('2021').tz_localize('UTC')])","handlingStrategy":"validation","validationCode":"def normalize_tzs(ts_list, target='UTC'):\n    out = []\n    for ts in ts_list:\n        ts = pd.Timestamp(ts)\n        if ts.tzinfo is None:\n            ts = ts.tz_localize(target)\n        else:\n            ts = ts.tz_convert(target)\n        out.append(ts)\n    return out","typeGuard":"def all_same_awareness(ts_list) -> bool:\n    tzs = {pd.Timestamp(t).tzinfo is not None for t in ts_list}\n    return len(tzs) == 1","tryCatchPattern":null,"preventionTips":["Enforce utc=True at pd.to_datetime for mixed inputs.","Validate tz homogeneity before constructing a DatetimeIndex.","Sanitize DB/JSON rows where tz presence varies."],"tags":["datetime","timezone","construction","pandas"],"analyzedSha":"71959b8cb9b2459c16e14b34f28b178ccfe14735","analyzedAt":"2026-08-07T01:30:20.476Z","schemaVersion":2},"datasetVersion":"2026-08-07T03:17:09.362Z"}