def decode_cf_datetime(
    num_dates,
    units: str,
    calendar: str | None = None,
    use_cftime: bool | None = None,
    time_unit: PDDatetimeUnitOptions = "ns",
) -> np.ndarray:
    """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.datetime64.

    Note that time unit in `units` must not be smaller than microseconds and
    not larger than days.

    See Also
    --------
    cftime.num2date
    """
    num_dates = to_numpy(num_dates)
    flat_num_dates = ravel(num_dates)
    if calendar is None:
        calendar = "standard"

    if use_cftime is None:
        try:
            dates = _decode_datetime_with_pandas(
                flat_num_dates, units, calendar, time_unit
            )
        except (KeyError, OutOfBoundsDatetime, OutOfBoundsTimedelta, OverflowError):
            dates = _decode_datetime_with_cftime(
                flat_num_dates.astype(float), units, calendar
            )
            # retrieve cftype
            dates_min = dates[np.nanargmin(num_dates)]
            dates_max = dates[np.nanargmax(num_dates)]
            cftype = type(dates_min)
            # create first day of gregorian calendar in current cf calendar type
            border = cftype(1582, 10, 15)
            # "ns" borders
            # between ['1677-09-21T00:12:43.145224193', '2262-04-11T23:47:16.854775807']
            lower = cftype(1677, 9, 21, 0, 12, 43, 145224)
            upper = cftype(2262, 4, 11, 23, 47, 16, 854775)

            if dates_min < border:
                if _is_standard_calendar(calendar):
                    emit_user_level_warning(
                        "Unable to decode time axis into full "
                        "numpy.datetime64 objects, continuing using "
                        "cftime.datetime objects instead, reason: dates prior "
                        "reform date (1582-10-15). To silence this warning specify "
                        "'use_cftime=True'.",
                        SerializationWarning,
                    )
            elif time_unit == "ns" and (dates_min < lower or dates_max > upper):
                emit_user_level_warning(
                    "Unable to decode time axis into full "
                    "numpy.datetime64[ns] objects, continuing using "
                    "cftime.datetime objects instead, reason: dates out "
                    "of range. To silence this warning use a coarser resolution "
                    "'time_unit' or specify 'use_cftime=True'.",
                    SerializationWarning,
                )
            elif _is_standard_calendar(calendar):
                dates = cftime_to_nptime(dates, time_unit=time_unit)
    elif use_cftime:
        dates = _decode_datetime_with_cftime(flat_num_dates, units, calendar)
    else:
        dates = _decode_datetime_with_pandas(flat_num_dates, units, calendar, time_unit)

    return reshape(dates, num_dates.shape)
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.datetime64.

    Note that time unit in `units` must not be smaller than microseconds and
    not larger than days.

    See Also
    --------
    cftime.num2date
    
xarray/coding/times.py