Path: blob/main/py-polars/tests/unit/functions/range/test_date_ranges.py
7884 views
from __future__ import annotations12from datetime import date3from typing import TYPE_CHECKING45import pandas as pd6import pytest78import polars as pl9from polars.exceptions import ComputeError10from polars.testing import assert_frame_equal, assert_series_equal1112if TYPE_CHECKING:13from polars._typing import ClosedInterval141516def test_date_ranges_lazy_with_literals() -> None:17df = pl.DataFrame({"misc": ["x"]}).with_columns(18pl.date_ranges(19start=date(2000, 1, 1),20end=date(2023, 8, 31),21interval="987d",22eager=False,23).alias("dts")24)25assert df.rows() == [26(27"x",28[29date(2000, 1, 1),30date(2002, 9, 14),31date(2005, 5, 28),32date(2008, 2, 9),33date(2010, 10, 23),34date(2013, 7, 6),35date(2016, 3, 19),36date(2018, 12, 1),37date(2021, 8, 14),38],39)40]41assert (42df.rows()[0][1]43== pd.date_range(44date(2000, 1, 1), date(2023, 12, 31), freq="987d"45).date.tolist()46)474849@pytest.mark.parametrize("low", ["start", pl.col("start")])50@pytest.mark.parametrize("high", ["stop", pl.col("stop")])51def test_date_ranges_lazy_with_expressions(52low: str | pl.Expr, high: str | pl.Expr53) -> None:54lf = pl.LazyFrame(55{56"start": [date(2015, 6, 30)],57"stop": [date(2022, 12, 31)],58}59)6061result = lf.with_columns(62pl.date_ranges(start=low, end=high, interval="678d", eager=False).alias("dts")63)6465assert result.collect().rows() == [66(67date(2015, 6, 30),68date(2022, 12, 31),69[70date(2015, 6, 30),71date(2017, 5, 8),72date(2019, 3, 17),73date(2021, 1, 23),74date(2022, 12, 2),75],76)77]7879df = pl.DataFrame(80{81"start": [date(2000, 1, 1), date(2022, 6, 1)],82"stop": [date(2000, 1, 2), date(2022, 6, 2)],83}84)8586result_df = df.with_columns(87pl.date_ranges(start=low, end=high, interval="1d").alias("dts")88)8990assert result_df.to_dict(as_series=False) == {91"start": [date(2000, 1, 1), date(2022, 6, 1)],92"stop": [date(2000, 1, 2), date(2022, 6, 2)],93"dts": [94[date(2000, 1, 1), date(2000, 1, 2)],95[date(2022, 6, 1), date(2022, 6, 2)],96],97}9899100def test_date_ranges_single_row_lazy_7110() -> None:101df = pl.DataFrame(102{103"name": ["A"],104"from": [date(2020, 1, 1)],105"to": [date(2020, 1, 2)],106}107)108result = df.with_columns(109pl.date_ranges(110start=pl.col("from"),111end=pl.col("to"),112interval="1d",113eager=False,114).alias("date_range")115)116expected = pl.DataFrame(117{118"name": ["A"],119"from": [date(2020, 1, 1)],120"to": [date(2020, 1, 2)],121"date_range": [[date(2020, 1, 1), date(2020, 1, 2)]],122}123)124assert_frame_equal(result, expected)125126127def test_date_ranges_eager() -> None:128start = pl.Series("start", [date(2022, 1, 1), date(2022, 1, 2)])129end = pl.Series("end", [date(2022, 1, 4), date(2022, 1, 3)])130131result = pl.date_ranges(start=start, end=end, eager=True)132133expected = pl.Series(134"start",135[136[date(2022, 1, 1), date(2022, 1, 2), date(2022, 1, 3), date(2022, 1, 4)],137[date(2022, 1, 2), date(2022, 1, 3)],138],139)140assert_series_equal(result, expected)141142143def test_date_ranges_broadcasting() -> None:144df = pl.DataFrame({"dates": [date(2021, 1, 1), date(2021, 1, 2), date(2021, 1, 3)]})145result = df.select(146pl.date_ranges(start="dates", end=date(2021, 1, 3)).alias("end"),147pl.date_ranges(start=date(2021, 1, 1), end="dates").alias("start"),148)149expected = pl.DataFrame(150{151"end": [152[date(2021, 1, 1), date(2021, 1, 2), date(2021, 1, 3)],153[date(2021, 1, 2), date(2021, 1, 3)],154[date(2021, 1, 3)],155],156"start": [157[date(2021, 1, 1)],158[date(2021, 1, 1), date(2021, 1, 2)],159[date(2021, 1, 1), date(2021, 1, 2), date(2021, 1, 3)],160],161}162)163assert_frame_equal(result, expected)164165166def test_date_ranges_broadcasting_fail() -> None:167start = pl.Series([date(2021, 1, 1), date(2021, 1, 2), date(2021, 1, 3)])168end = pl.Series([date(2021, 1, 2), date(2021, 1, 3)])169170with pytest.raises(171ComputeError, match=r"lengths of `start` \(3\) and `end` \(2\) do not match"172):173pl.date_ranges(start=start, end=end, eager=True)174175176@pytest.mark.parametrize(177("closed", "expected"),178[179(180"both",181[182[183date(2025, 1, 1),184date(2025, 1, 3),185date(2025, 1, 5),186date(2025, 1, 7),187],188[189date(2025, 1, 11),190date(2025, 1, 13),191date(2025, 1, 15),192date(2025, 1, 17),193],194],195),196(197"left",198[199[200date(2025, 1, 1),201date(2025, 1, 3),202date(2025, 1, 5),203date(2025, 1, 7),204],205[206date(2025, 1, 11),207date(2025, 1, 13),208date(2025, 1, 15),209date(2025, 1, 17),210],211],212),213(214"right",215[216[date(2025, 1, 3), date(2025, 1, 5), date(2025, 1, 7)],217[date(2025, 1, 13), date(2025, 1, 15), date(2025, 1, 17)],218],219),220(221"none",222[223[date(2025, 1, 3), date(2025, 1, 5), date(2025, 1, 7)],224[date(2025, 1, 13), date(2025, 1, 15), date(2025, 1, 17)],225],226),227],228)229def test_date_ranges_start_end_interval_forwards(230closed: ClosedInterval,231expected: list[date],232) -> None:233df = pl.DataFrame(234{235"start": [date(2025, 1, 1), date(2025, 1, 11)],236"end": [date(2025, 1, 8), date(2025, 1, 18)],237}238)239result = df.select(240dates=pl.date_ranges(start="start", end="end", interval="2d", closed=closed)241)242assert_frame_equal(result, pl.Series("dates", expected).to_frame())243244245