home / github / issue_comments

Menu
  • GraphQL API
  • Search all tables

issue_comments: 374711420

This data as json

html_url issue_url id node_id user created_at updated_at author_association body reactions performed_via_github_app issue
https://github.com/pydata/xarray/pull/1252#issuecomment-374711420 https://api.github.com/repos/pydata/xarray/issues/1252 374711420 MDEyOklzc3VlQ29tbWVudDM3NDcxMTQyMA== 6628425 2018-03-20T18:39:56Z 2018-03-20T18:39:56Z MEMBER

It occurred to me that netcdftime.num2date can return datetime.datetime objects in certain circumstances (not just objects that subclass netcdftime.datetime). 5e1c4a8 provides fixes to allow things to work with datetime.datetime objects as well as more test coverage.

One thing that makes the logic a bit messier here is that determining the calendar type for encoding datetime.datetime objects for faithful roundtripping is a bit complicated. As far as I can tell, there are two scenarios, each with their own branches of logic: 1. Arrays where the minimum date is before the start of the Gregorian calendar (1582-10-15) * If the dates have the type datetime.datetime we encode them using the 'gregorian' calendar. * If the dates have the type netcdftime.DatetimeGregorian we encode them using the 'standard' calendar type. 2. Arrays where the minimum date is on or after the start of the Gregorian calendar (1582-10-15) * In this scenario, I'm not sure if it is possible to get num2date to return objects of type netcdftime.DatetimeGregorian. Therefore, regardless of whether the dates are of type datetime.datetime or netcdftime.DatetimeGregorian, we encode them using the 'standard' calendar type.

The rationale behind this more complicated logic has to do with how it appears netcdftime.num2date behaves. Here are some minimal examples:

```python

from netcdftime import date2num, num2date, DatetimeGregorian from datetime import datetime

units = 'days since 1582-01-01'

Case with minimum date before start of Gregorian calendar

arr = date2num([datetime(1582, 10, 1), datetime(1582, 10, 15)], units=units)

To recover datetime.datetime objects, we need to use calendar='gregorian'

num2date(arr, units=units, calendar='gregorian') array([datetime.datetime(1582, 10, 1, 0, 0), datetime.datetime(1582, 10, 15, 0, 0)], dtype=object) num2date(arr, units=units, calendar='standard')

Using calendar='standard' results in netcdftime.DatetimeGregorian objects

array([netcdftime._netcdftime.DatetimeGregorian(1582, 10, 1, 0, 0, 0, 0, -1, 1), netcdftime._netcdftime.DatetimeGregorian(1582, 10, 15, 0, 0, 0, 0, -1, 1)], dtype=object)

Case with minimum date after start of Gregorian calendar

arr = date2num([datetime(1582, 10, 15), datetime(1582, 10, 16)], units=units)

Regardless of the calendar type used for decoding, we get datetime.datetime objects

num2date(arr, units=units, calendar='gregorian') array([datetime.datetime(1582, 10, 15, 0, 0), datetime.datetime(1582, 10, 16, 0, 0)], dtype=object) num2date(arr, units=units, calendar='standard') array([datetime.datetime(1582, 10, 15, 0, 0), datetime.datetime(1582, 10, 16, 0, 0)], dtype=object) ```

Given the fact that it does not seem possible to decode times after the start of the Gregorian calendar into dates of type netcdftime.DatetimeGregorian it is surprising that test_roundtrip_netcdftime_datetime_data_post_gregorian passes for DatetimeGregorian objects. It turns out it works, because timedelta arithmetic is valid between DatetimeGregorian and datetime.datetime objects for dates after the start of the Gregorian calendar: ```python

DatetimeGregorian(1, 1, 1) - datetime(1, 1, 1) Traceback (most recent call last): File "<stdin>", line 1, in <module> File "netcdftime/_netcdftime.pyx", line 1624, in netcdftime._netcdftime.datetime.sub ValueError: cannot compute the time difference between dates with different calendars DatetimeGregorian(1582, 10, 30) - datetime(1582, 10, 16) datetime.timedelta(14) ``` (though maybe I should add an assert statement to check the date types, which would cause it to fail as currently constructed).

@jswhit, @jhamman -- is this behavior expected for netcdftime? Is there a recommended robust way for determining the calendar type for roundtripping between date2num and num2date, or is what I have in times.py#L248-L268 sufficient?

{
    "total_count": 0,
    "+1": 0,
    "-1": 0,
    "laugh": 0,
    "hooray": 0,
    "confused": 0,
    "heart": 0,
    "rocket": 0,
    "eyes": 0
}
  205473898
Powered by Datasette · Queries took 0.623ms · About: xarray-datasette