diff --git a/pyfacts/utils.py b/pyfacts/utils.py index 11522f0..84e32d1 100644 --- a/pyfacts/utils.py +++ b/pyfacts/utils.py @@ -144,13 +144,43 @@ def _preprocess_match_options(as_on_match: str, prior_match: str, closest: str) return as_on_delta, prior_delta +def _preprocess_from_to_date( + from_date: datetime.date | str, + to_date: datetime.date | str, + time_series: Mapping = None, + align_dates: bool = True, + return_period_unit: Literal["years", "months", "days"] = None, + return_period_value: int = None, + as_on_match: str = "closest", + prior_match: str = "closest", + closest: Literal["previous", "next", "exact"] = "previous", +) -> tuple: + + as_on_match, prior_match = _preprocess_match_options(as_on_match, prior_match, closest) + + if (from_date is None or to_date is None) and time_series is None: + raise ValueError("Provide either to_date and from_date or time_series data") + + if time_series is not None and (return_period_unit is None or return_period_value is None): + raise ValueError("Provide return period for calculation of from_date") + + if from_date is None: + expected_start_date = time_series.start_date + relativedelta(**{return_period_unit: return_period_value}) + from_date = _find_closest_date(time_series.data, expected_start_date, 999, as_on_match, "fail")[0] + + if to_date is None: + to_date = time_series.end_date + + return from_date, to_date + + def _find_closest_date( data: Mapping[datetime.datetime, float], date: datetime.datetime, limit_days: int, delta: datetime.timedelta, if_not_found: Literal["fail", "nan"], -): +) -> Tuple[datetime.datetime, float]: """Helper function to find data for the closest available date""" if delta.days < 0 and date < min(data):