Modflow6 utility function to transform float64 time entries to a datetime/date-index type
Unlike imod/imod-wq, modflow6 doesn't use (force) an internal calendar. Rather, every simulation starts at t=0.0, and all timestamps are simple float64 values.
For further post-processing, having datetimes is convenient, but datetimes are famously complicated: https://stackoverflow.com/questions/13703720/converting-between-datetime-timestamp-and-datetime64
"welcome to hell"
I guess with a signature like this:
def to_timestamp(time, start_date, unit="D", calendar=cftime.DatetimeGregorian):
raise NotImplementedError
With the following typical use:
heads = imod.mf6.read_hds("example.hds", "example.grb")
heads["time"] = imod.util.to_timestamp(heads["time"], start_date="2000-01-01")
I'm a little conflicted on what to do about the datetime types. Primary use is for xarray coordinates. Default is then a Pandas DatetimeIndex. It's clear that that only works for Gregorian calendars, but the nanosecond resolution gives a pretty narrow time frame: [ 1678 AD, 2262 AD].
Guess it's best to be pragmatic?
- Gregorian, all times within [1678 AD, 2262 AD]: numpy.datetime64("ns")
- Non-Gregorian: CFTimeIndex
- Gregorian, times outside of frame: CFTimeIndex
Or maybe make it more explicit: default calendar value is None, in which case it tries numpy.datetime64("ns") and errors if it doesn't fit. And whenever cftime is required, the user should just pass the desired calendar.
Otherwise I can imagine the following happening:
- Test model with a "short" time window: datetime64("ns"), works great
- Do actual run with longer time windows: get (esoteric) errors due to conflicts between numpy datetimes and cftime
Better instead:
- Test model with a "short" time window: datetime64("ns"), works great
- Do actual run with longer time windows: Get error mentioning the time frame no longer fits, and a cftime calendar has to set explicity.