Is there a built-in way to convert datetimes to cftime in xarray?

Viewed 51

I would like to plot two time series, one of which is in cftime and the other in datetime.

One possibility is to convert cftime to datetime, but this might give strange results for nonstandard cftime calendars (e.g. NoLeap). As such, I am trying to convert the datetime to cftime.

I can brute-force it as follows, but is there a built-in method available?

>>> import pandas as pd
>>> import xarray as xr
>>>
>>> da = xr.DataArray(
...     [1, 2], coords={"time": pd.to_datetime(["2000-01-01", "2000-02-02"])}, dims=["time"]
... )
>>> print(da.time)
<xarray.DataArray 'time' (time: 2)>
array(['2000-01-01T00:00:00.000000000', '2000-02-02T00:00:00.000000000'],
      dtype='datetime64[ns]')
Coordinates:
  * time     (time) datetime64[ns] 2000-01-01 2000-02-02
>>>
>>>
>>> import cftime
>>>
>>>
>>> def datetime_to_cftime(dates, kwargs={}):
...     return [
...         cftime.datetime(
...             date.dt.year,
...             date.dt.month,
...             date.dt.day,
...             date.dt.hour,
...             date.dt.minute,
...             date.dt.second,
...             date.dt.microsecond,
...             **kwargs
...         )
...         for date in dates
...     ]
...
>>> datetime_to_cftime(da.time)
[cftime.datetime(2000, 1, 1, 0, 0, 0, 0, calendar='standard', has_year_zero=False), cftime.datetime(2000, 2, 2, 0, 0, 0, 0, calendar='standard', has_year_zero=False)]
1 Answers

Indeed you might consider using DataArray.convert_calendar. For example if you would like to convert datetime64 values to cftime.DatetimeNoLeap objects, you could do something like this:

>>> da.convert_calendar("noleap")
<xarray.DataArray (time: 2)>
array([1., 2.])
Coordinates:
  * time     (time) object 2000-01-01 00:00:00 2000-02-02 00:00:00

This method is new as of xarray version 0.20.0.

Related