Skip to content

date_range needs more flexibility : generate date at middle of months/hours like cftime_range can #10206

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
oliviermarti opened this issue Apr 7, 2025 · 2 comments

Comments

@oliviermarti
Copy link

What is your issue?

Hi,

When runnning :

xr.date_range(start="1900-01-15 00:00:00", periods=12, freq="1MS", normalize=True , name='time', inclusive='both', calendar='gregorian', unit='s', use_cftime=True)

I get the time values :

 CFTimeIndex([1900-02-01 00:00:00, 1900-03-01 00:00:00, 1900-04-01 00:00:00,
             1900-05-01 00:00:00, 1900-06-01 00:00:00, 1900-07-01 00:00:00,
             1900-08-01 00:00:00, 1900-09-01 00:00:00, 1900-10-01 00:00:00,
             1900-11-01 00:00:00, 1900-12-01 00:00:00, 1901-01-01 00:00:00],
            dtype='object', length=12, calendar='standard', freq='MS')

It starts at the end of January/start of February. Not at the middle of January.

I would like to use date_range to generate a time axis with values every month, but at (approximate) middle of months.

Most CMIP models provides a time axis with value at the middle of a period, and provides time_bounds at the start/end of the periods.

For tests cases, I need to generate such time values.

I can generates them by this rather ugly :
time = [ xr.date_range(start=f"{1900+ii//12:04}-{ii%12+1:02}-15 00:00", periods=1, **kwargs).values[0] for ii in np.arange(12) ]

or by a using the deprecated function cftime_range

xr.cftime_range(start="1900-01-15 00:00:00", end="1900-12-15 00:00:00", periods=12,
    normalize=False,  name='time', #inclusive='both',  calendar='gregorian' )

Could it be possible to get back the flexibility of cftime_range ?

Note that the problem is the same when generating an axis with hourly values at the middle of each hour.

Thanks,

Olivier

@oliviermarti oliviermarti added the needs triage Issue that has not been reviewed by xarray team member label Apr 7, 2025
@spencerkclark
Copy link
Member

With use_cftime=True, xarray.date_range calls xarray.cftime_range under the hood, so I think if you just harmonize the arguments you pass to cftime_range with those you pass to date_range—note they are different in your example—you should be able to get identical results:

>>> xr.cftime_range(start="1900-01-15 00:00:00", end="1900-12-15 00:00:00", periods=12, normalize=False,  name='time', calendar='gregorian')
<stdin>:1: DeprecationWarning: cftime_range() is deprecated, please use xarray.date_range(..., use_cftime=True) instead.
CFTimeIndex([1900-01-15 00:00:00, 1900-02-14 08:43:38.181818, 1900-03-16 17:27:16.363636,
             1900-04-16 02:10:54.545455, 1900-05-16 10:54:32.727273, 1900-06-15 19:38:10.909091,
             1900-07-16 04:21:49.090909, 1900-08-15 13:05:27.272727, 1900-09-14 21:49:05.454545,
             1900-10-15 06:32:43.636364, 1900-11-14 15:16:21.818182, 1900-12-15 00:00:00],
            dtype='object', length=12, calendar='standard', freq=None)
>>> xr.date_range(start="1900-01-15 00:00:00", end="1900-12-15 00:00:00", periods=12, normalize=False,  name='time', calendar='gregorian', use_cftime=True)
CFTimeIndex([1900-01-15 00:00:00, 1900-02-14 08:43:38.181818, 1900-03-16 17:27:16.363636,
             1900-04-16 02:10:54.545455, 1900-05-16 10:54:32.727273, 1900-06-15 19:38:10.909091,
             1900-07-16 04:21:49.090909, 1900-08-15 13:05:27.272727, 1900-09-14 21:49:05.454545,
             1900-10-15 06:32:43.636364, 1900-11-14 15:16:21.818182, 1900-12-15 00:00:00],
            dtype='object', length=12, calendar='standard', freq=None)

In case it is helpful to you or anyone else who comes across this issue, if you would like values exactly at monthly midpoints, it is not too difficult to achieve with timedelta arithmetic:

>>> times = xr.date_range("1900-01", freq="MS", periods=13, use_cftime=True)
>>> times[:-1] + (times[1:] - times[:-1]) / 2
CFTimeIndex([1900-01-16 12:00:00, 1900-02-15 00:00:00, 1900-03-16 12:00:00,
             1900-04-16 00:00:00, 1900-05-16 12:00:00, 1900-06-16 00:00:00,
             1900-07-16 12:00:00, 1900-08-16 12:00:00, 1900-09-16 00:00:00,
             1900-10-16 12:00:00, 1900-11-16 00:00:00, 1900-12-16 12:00:00],
            dtype='object', length=12, calendar='standard', freq=None)

@spencerkclark spencerkclark removed the needs triage Issue that has not been reviewed by xarray team member label Apr 7, 2025
@spencerkclark
Copy link
Member

I am going to go ahead and close this issue, but please feel free to re-open if you feel more discussion is needed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants