{"record":{"id":"ce02c3ab5c8509a9","repo":"pandas-dev/pandas","slug":"left-and-right-must-have-the-same-time-zone-got","errorCode":null,"errorMessage":"left and right must have the same time zone, got '{left.tz}' and '{right.tz}'","messagePattern":"left and right must have the same time zone, got '(.+?)' and '(.+?)'","errorType":"validation","errorClass":"ValueError","httpStatus":null,"severity":"error","filePath":"pandas/core/arrays/interval.py","lineNumber":343,"sourceCode":"            isinstance(left.dtype, CategoricalDtype)\n            or is_string_dtype(left.dtype)\n            or is_string_dtype(right.dtype)\n        ):\n            # GH 19016, GH 66518: reject unsupported right-side dtypes too.\n            msg = (\n                \"category, object, and string subtypes are not supported \"\n                \"for IntervalArray\"\n            )\n            raise TypeError(msg)\n        if isinstance(left, ABCPeriodIndex):\n            msg = \"Period dtypes are not supported, use a PeriodIndex instead\"\n            raise ValueError(msg)\n        if isinstance(left, ABCDatetimeIndex) and str(left.tz) != str(right.tz):\n            msg = (\n                \"left and right must have the same time zone, got \"\n                f\"'{left.tz}' and '{right.tz}'\"\n            )\n            raise ValueError(msg)\n        elif needs_i8_conversion(left.dtype) and left.unit != right.unit:\n            # e.g. m8[s] vs m8[ms], try to cast to a common dtype GH#55714\n            left_arr, right_arr = left._data._ensure_matching_resos(right._data)\n            left = ensure_index(left_arr)\n            right = ensure_index(right_arr)\n\n        # For dt64/td64 we want DatetimeArray/TimedeltaArray instead of ndarray\n        left = ensure_wrapped_if_datetimelike(left)\n        left = extract_array(left, extract_numpy=True)\n        right = ensure_wrapped_if_datetimelike(right)\n        right = extract_array(right, extract_numpy=True)\n\n        if isinstance(left, ArrowExtensionArray) or isinstance(\n            right, ArrowExtensionArray\n        ):\n            pass\n        else:\n            lbase = getattr(left, \"_ndarray\", left)","sourceCodeStart":325,"sourceCodeEnd":361,"githubUrl":"https://github.com/pandas-dev/pandas/blob/3b7651241d4da534b3559b60ef128e1c34f54116/pandas/core/arrays/interval.py#L325-L361","documentation":"Raised when both left and right are DatetimeIndex but their time zones differ (compared by `str(left.tz) != str(right.tz)`). IntervalArray requires tz-aware endpoints to share one timezone so the resulting dtype is unambiguous.","triggerScenarios":"left tz-aware UTC, right naive or tz-aware US/Eastern; mixing timestamps parsed with different `tz_localize`/`tz_convert` calls; one side from a tz-aware column, the other from a UTC database field.","commonSituations":"ETL pipelines combining sources with different timezone conventions; DST-handling refactors; one side accidentally stripped of tz via `.dt.tz_localize(None)`.","solutions":["Localise or convert both sides to the same tz: `right = right.tz_localize('UTC')` (if naive) or `right = right.tz_convert(left.tz)` (if aware).","Strip tz from both sides if naive comparison is acceptable: `left.tz_localize(None)`, `right.tz_localize(None)`.","Verify equality with `str(left.tz) == str(right.tz)` before constructing."],"exampleFix":"# before\nl = pd.date_range('2020', periods=2, tz='UTC')\nr = pd.date_range('2020', periods=2, tz='US/Eastern')\nIntervalArray.from_arrays(l, r)\n\n# after\nIntervalArray.from_arrays(l, r.tz_convert('UTC'))","handlingStrategy":"validation","validationCode":"import pandas as pd\n\ndef unify_tz(left, right, target='UTC'):\n    if getattr(left.dtype, 'tz', None) or getattr(right.dtype, 'tz', None):\n        if left.tz is None:\n            left = left.tz_localize(target)\n        if right.tz is None:\n            right = right.tz_localize(target)\n        left = left.tz_convert(target)\n        right = right.tz_convert(target)\n    return left, right","typeGuard":"import pandas as pd\n\ndef same_timezone(left, right) -> bool:\n    lt = getattr(left, 'tz', None)\n    rt = getattr(right, 'tz', None)\n    return str(lt) == str(rt)","tryCatchPattern":"try:\n    arr = IntervalArray.from_arrays(left, right)\nexcept ValueError as e:\n    if 'same time zone' in str(e):\n        right = right.tz_convert(left.tz) if right.tz else right.tz_localize(left.tz)\n        arr = IntervalArray.from_arrays(left, right)\n    else:\n        raise","preventionTips":["Localise/convert both endpoints to a single canonical tz (e.g. UTC) at ingestion.","Assert str(left.tz) == str(right.tz) before constructing intervals.","Beware `.dt.tz_localize(None)` calls that strip tz on one side only."],"tags":["interval","timezone","datetimeindex","value-error"],"backgroundTag":null,"analyzedSha":"3b7651241d4da534b3559b60ef128e1c34f54116","analyzedAt":"2026-08-11T22:10:44.015Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}