diff --git a/doc/release_notes.rst b/doc/release_notes.rst index ada70ec6..8cecfcd4 100644 --- a/doc/release_notes.rst +++ b/doc/release_notes.rst @@ -29,7 +29,7 @@ Version 0.9.1 * ``Model.remove_variables`` no longer raises an ``IndexError`` on a quadratic objective. A quadratic term is dropped when any of its factors uses the removed variable. (`#883 `__, `#895 `__) * The Xpress interface no longer calls API functions deprecated in Xpress 9.8. (`#880 `__) * The ``docs`` extra no longer pins ``numpy<2``. (`#869 `__) - +* Using timezone-aware ``DatetimeIndex`` coordinates in a model no longer raises a ``ValueError``. The index is now retrieved directly via ``DataArray.to_index()`` instead of rebuilding it with ``pd.Index()``, which dropped the timezone info and failed during alignment. (`#898 `__) Version v0.9.0 -------------- diff --git a/linopy/alignment.py b/linopy/alignment.py index 13126b85..541aa55a 100644 --- a/linopy/alignment.py +++ b/linopy/alignment.py @@ -172,9 +172,11 @@ def _coords_to_dict( def _as_index(coord_values: Any) -> pd.Index: - return ( - coord_values if isinstance(coord_values, pd.Index) else pd.Index(coord_values) - ) + if isinstance(coord_values, DataArray): + return coord_values.to_index() + if isinstance(coord_values, pd.Index): + return coord_values + return pd.Index(coord_values) def _as_multiindex(coord_values: Any) -> pd.MultiIndex | None: diff --git a/test/test_alignment.py b/test/test_alignment.py index 73d2cfdb..a6eb2b09 100644 --- a/test/test_alignment.py +++ b/test/test_alignment.py @@ -572,6 +572,17 @@ def test_invalid_entry_raises_typeerror( class TestAddVariablesCoords: """End-to-end: each coords / dims form sets the variable's dimensions.""" + @staticmethod + def _datetime_coordinates(timezone: str | None) -> xr.Coordinates: + time = pd.date_range( + "2025-10-26 00:00", + periods=5, + freq="h", + tz=timezone, + name="time", + ) + return xr.Coordinates({"time": time}) + @pytest.mark.parametrize( "coords, dims, expected_dims", [ @@ -586,6 +597,9 @@ class TestAddVariablesCoords: ([np.array([0, 1, 2])], None, ("dim_0",)), ([pd.Index([0, 1, 2])], None, ("dim_0",)), ([("origin", ["a", "b"]), ("dest", ["x", "y"])], None, ("origin", "dest")), + (_datetime_coordinates(None), None, ("time",)), + (_datetime_coordinates("UTC"), None, ("time",)), + (_datetime_coordinates("Europe/Berlin"), None, ("time",)), ], ids=[ "tuple", @@ -599,6 +613,9 @@ class TestAddVariablesCoords: "ndarray", "unnamed-index", "multiple-tuples", + "xarray-datetime-naive", + "xarray-datetime-utc", + "xarray-datetime-dst", ], ) def test_coords_set_variable_dims(