Repository: NCAR/geocat-comp

Issue:
Support for non-nanosecond datetime
In short, the broader ecosystem is working to support non-nanosecond datetime objects (see: https://github.com/pydata/xarray/issues/7493) in Pandas 2+ and Xarray's release last month.  This topic was brought to my attention by the recent upstream dev issues w/ Xarray (#681).  

As I was digging through our climatology code today, I noticed we have some things hard coded that will break (in some cases) with these ecosystem changes.

We'll likely want to pin some dependencies and/or make changes and add tests to support this.

Related:
* [Helpful Xarray docs on time coding](https://docs.xarray.dev/en/stable/internals/time-coding.html#internals-timecoding)
* [Xarray docs on non-standard calendars and dates outside the precision range](https://docs.xarray.dev/en/stable/user-guide/weather-climate.html#non-standard-calendars-and-dates-outside-the-precision-range)

Hints from issue comments:
@kafitzgerald: It looks like we already have versions of these packages with support for non-nanosecond datetimes installing in our test environments.  Our tests aren't failing, but I suspect that's because we're not testing for this.

`_infer_calendar_name` and the test suite are probably where changes are needed.

Also worth noting that there's some overlap here with #508.

Solution patch:
diff --git a/docs/release-notes.rst b/docs/release-notes.rst
index 5de26816..6720d307 100644
--- a/docs/release-notes.rst
+++ b/docs/release-notes.rst
@@ -11,9 +11,13 @@ Release Notes
 vYYYY.MM.## (unreleased)
 ------------------------
 
+Enhancements
+^^^^^^^^^^^^
+* Add tests and support for non-nanosecond datetime objects by `Katelyn FitzGerald`_ in (:pr:`691`)
+
 Maintenance
 ^^^^^^^^^^^
-* Add support and testing for Python 3.13 by`Katelyn FitzGerald`_ in (:pr:`687`)
+* Add support and testing for Python 3.13 by `Katelyn FitzGerald`_ in (:pr:`687`)
 * Remove NumPy version pin by `Katelyn FitzGerald`_ in (:pr:`686`)
 
 v2025.01.0 (January 28, 2025)
diff --git a/geocat/comp/climatologies.py b/geocat/comp/climatologies.py
index 6e5a2425..f183b3a0 100644
--- a/geocat/comp/climatologies.py
+++ b/geocat/comp/climatologies.py
@@ -105,7 +105,8 @@ def _infer_calendar_name(dates):
     anytime. It was copied to preserve the version that is compatible with
     functions in climatologies.py
     """
-    if np.asarray(dates).dtype == "datetime64[ns]":
+
+    if np.issubdtype(dates.dtype, np.datetime64):
         return "proleptic_gregorian"
     else:
         return np.asarray(dates).ravel()[0].calendar


Test patch:
diff --git a/test/test_climatologies.py b/test/test_climatologies.py
index 71c28aa3..a73c13d2 100644
--- a/test/test_climatologies.py
+++ b/test/test_climatologies.py
@@ -6,6 +6,7 @@
 import xarray as xr
 
 from geocat.comp import climate_anomaly, month_to_season, calendar_average, climatology_average
+from geocat.comp.climatologies import _infer_calendar_name
 
 
 ##### Helper Functions #####
@@ -943,3 +944,9 @@ def test_non_standard_calendars_climatology_average(self, name, dset,
                                                         expected) -> None:
         result = climatology_average(dset, freq='month')
         xr.testing.assert_allclose(result, expected)
+
+
+@pytest.mark.parametrize("units", ("s", "ms", "us", "ns"))
+def test_units_infer_calendar_name(units):
+    time = xr.date_range("2000-01-01", periods=10, freq="1D", unit=units)
+    assert _infer_calendar_name(time) == "proleptic_gregorian"