Given an array of numeric dates in netCDF format, convert it into a numpy array of date time objects. For standard (Gregorian) calendars, this function uses vectorized operations, which makes it much faster than cftime.num2date. In such a case, the returned array will be of type np.
(
num_dates,
units: str,
calendar: str | None = None,
use_cftime: bool | None = None,
time_unit: PDDatetimeUnitOptions = "ns",
)
| 533 | |
| 534 | |
| 535 | def decode_cf_datetime( |
| 536 | num_dates, |
| 537 | units: str, |
| 538 | calendar: str | None = None, |
| 539 | use_cftime: bool | None = None, |
| 540 | time_unit: PDDatetimeUnitOptions = "ns", |
| 541 | ) -> np.ndarray: |
| 542 | """Given an array of numeric dates in netCDF format, convert it into a |
| 543 | numpy array of date time objects. |
| 544 | |
| 545 | For standard (Gregorian) calendars, this function uses vectorized |
| 546 | operations, which makes it much faster than cftime.num2date. In such a |
| 547 | case, the returned array will be of type np.datetime64. |
| 548 | |
| 549 | Note that time unit in `units` must not be smaller than microseconds and |
| 550 | not larger than days. |
| 551 | |
| 552 | See Also |
| 553 | -------- |
| 554 | cftime.num2date |
| 555 | """ |
| 556 | num_dates = to_numpy(num_dates) |
| 557 | flat_num_dates = ravel(num_dates) |
| 558 | if calendar is None: |
| 559 | calendar = "standard" |
| 560 | |
| 561 | if use_cftime is None: |
| 562 | try: |
| 563 | dates = _decode_datetime_with_pandas( |
| 564 | flat_num_dates, units, calendar, time_unit |
| 565 | ) |
| 566 | except (KeyError, OutOfBoundsDatetime, OutOfBoundsTimedelta, OverflowError): |
| 567 | dates = _decode_datetime_with_cftime( |
| 568 | flat_num_dates.astype(float), units, calendar |
| 569 | ) |
| 570 | # retrieve cftype |
| 571 | dates_min = dates[np.nanargmin(num_dates)] |
| 572 | dates_max = dates[np.nanargmax(num_dates)] |
| 573 | cftype = type(dates_min) |
| 574 | # create first day of gregorian calendar in current cf calendar type |
| 575 | border = cftype(1582, 10, 15) |
| 576 | # "ns" borders |
| 577 | # between ['1677-09-21T00:12:43.145224193', '2262-04-11T23:47:16.854775807'] |
| 578 | lower = cftype(1677, 9, 21, 0, 12, 43, 145224) |
| 579 | upper = cftype(2262, 4, 11, 23, 47, 16, 854775) |
| 580 | |
| 581 | if dates_min < border: |
| 582 | if _is_standard_calendar(calendar): |
| 583 | emit_user_level_warning( |
| 584 | "Unable to decode time axis into full " |
| 585 | "numpy.datetime64 objects, continuing using " |
| 586 | "cftime.datetime objects instead, reason: dates prior " |
| 587 | "reform date (1582-10-15). To silence this warning specify " |
| 588 | "'use_cftime=True'.", |
| 589 | SerializationWarning, |
| 590 | ) |
| 591 | elif time_unit == "ns" and (dates_min < lower or dates_max > upper): |
| 592 | emit_user_level_warning( |
searching dependent graphs…