A PR to fix this will need
- a test in the autotest suite to confirm using the idiomatic current style in '~/gdal/autotest/ ' for Zarr
- a short summary reference an unsubmitted enhancment request (based on zarr-v3-numpy-datetime64.md)
- documentation is possibly not required, unless there are mentions of existing extensions support in the current documentation
The change is localized. The data type parsing for V3 lives in frmts/zarr/zarr_v3_array.cpp (or nearby). There'll be a section that maps V3 type strings/objects to GDALDataType. Right now it handles the core types ("float32" → GDT_Float32, "int64" → GDT_Int64, etc.) but has no codepath for extension type JSON objects. The fix is adding a branch that recognizes {"name": "numpy.datetime64", ...} and maps it to GDT_Int64.
The 4D failure should fix itself. Once the time array opens as Int64, dimension resolution will work normally — it can read the int64 values, count the extra dimensions correctly, and :0,0 will just work. You shouldn't need to touch the dimension indexing logic at all.
There's precedent in the codebase. The V2 side already handles numpy dtype strings for various types, and the V3 data type parser already handles JSON objects for some types (just not extension types yet). The pattern to follow exists.
Things to watch for:
- The metadata side — storing units: "nanoseconds since 1970-01-01T00:00:00Z" as an attribute on the array so downstream consumers know what the int64 values mean. This is the "nice to have" that Even mentioned in #3896 ("we could likely implement them as double if needed").
numpy.timedelta64while you're in there — same pattern, same registry, same fix. Might as well.- Tests — GDAL's test suite is thorough. autotest/gdrivers/zarr.py will have the existing Zarr tests. Adding a V3 test case with a datetime64 coordinate (similar to your script) would strengthen the PR.
- Even's comment about mapping to double rather than int64 — nanosecond epoch values overflow float64 precision, so Int64 is the right choice. But worth a comment in the PR explaining why.
Starting point is 'frmts/zarr/', grep to find the exact insertion point would be something like grep -n "data_type\|GDT_Int64\|Invalid or unsupported format" frmts/zarr/zarr_v3*.cpp
original zarr: 'ZARR:"/vsigs/nmfs_odp_nwfsc/CB/fish-pace-datasets/chla-z/zarr"'