Generate a datetime array with the same frequency, start and end as another one, but in a different calendar. Parameters ---------- source : DataArray, CFTimeIndex, or pd.DatetimeIndex 1D datetime array calendar : str New calendar name. use_cftime : bool, opt
(source, calendar, use_cftime=None)
| 1551 | |
| 1552 | |
| 1553 | def date_range_like(source, calendar, use_cftime=None): |
| 1554 | """Generate a datetime array with the same frequency, start and end as |
| 1555 | another one, but in a different calendar. |
| 1556 | |
| 1557 | Parameters |
| 1558 | ---------- |
| 1559 | source : DataArray, CFTimeIndex, or pd.DatetimeIndex |
| 1560 | 1D datetime array |
| 1561 | calendar : str |
| 1562 | New calendar name. |
| 1563 | use_cftime : bool, optional |
| 1564 | If True, the output uses :py:class:`cftime.datetime` objects. |
| 1565 | If None (default), :py:class:`numpy.datetime64` values are used if possible. |
| 1566 | If False, :py:class:`numpy.datetime64` values are used or an error is raised. |
| 1567 | |
| 1568 | Returns |
| 1569 | ------- |
| 1570 | DataArray |
| 1571 | 1D datetime coordinate with the same start, end and frequency as the |
| 1572 | source, but in the new calendar. The start date is assumed to exist in |
| 1573 | the target calendar. If the end date doesn't exist, the code tries 1 |
| 1574 | and 2 calendar days before. There is a special case when the source time |
| 1575 | series is daily or coarser and the end of the input range is on the |
| 1576 | last day of the month. Then the output range will also end on the last |
| 1577 | day of the month in the new calendar. |
| 1578 | """ |
| 1579 | from xarray.coding.frequencies import infer_freq |
| 1580 | from xarray.core.dataarray import DataArray |
| 1581 | |
| 1582 | if not isinstance(source, pd.DatetimeIndex | CFTimeIndex) and ( |
| 1583 | (isinstance(source, DataArray) and (source.ndim != 1)) |
| 1584 | or not _contains_datetime_like_objects(source.variable) |
| 1585 | ): |
| 1586 | raise ValueError( |
| 1587 | "'source' must be a 1D array of datetime objects for inferring its range." |
| 1588 | ) |
| 1589 | |
| 1590 | freq = infer_freq(source) |
| 1591 | if freq is None: |
| 1592 | raise ValueError( |
| 1593 | "`date_range_like` was unable to generate a range as the source frequency was not inferable." |
| 1594 | ) |
| 1595 | |
| 1596 | # TODO remove once requiring pandas >= 2.2 |
| 1597 | freq = _legacy_to_new_freq(freq) |
| 1598 | |
| 1599 | use_cftime = _should_cftime_be_used(source, calendar, use_cftime) |
| 1600 | |
| 1601 | source_start = source.values.min() |
| 1602 | source_end = source.values.max() |
| 1603 | |
| 1604 | freq_as_offset = to_offset(freq) |
| 1605 | if freq_as_offset.n < 0: |
| 1606 | source_start, source_end = source_end, source_start |
| 1607 | |
| 1608 | if is_np_datetime_like(source.dtype): |
| 1609 | # We want to use datetime fields (datetime64 object don't have them) |
| 1610 | source_calendar = "standard" |
searching dependent graphs…