Skip to content
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

[Bug]: Writing out decoded time coordinates with non-CF time units breaks #397

Open
tomvothecoder opened this issue Jan 5, 2023 · 0 comments
Labels
type: bug Inconsistencies or issues which will cause an issue or problem for users or implementors.

Comments

@tomvothecoder
Copy link
Collaborator

tomvothecoder commented Jan 5, 2023

What happened?

When xarray writes datasets to a file, it uses cftime.date2num() which has restrictions on which units and calendars are compatible.

units: a string of the form since describing the time units. can be days, hours, minutes, seconds, milliseconds or microseconds. is the time origin. months since is allowed only for the 360_day calendar and common_years since is allowed only for the 365_day calendar.
-- https://unidata.github.io/cftime/api.html#cftime.date2num

Example:

Let's say we open up a dataset with the following metadata for time coordinates:

  • units = "months since 1800"
  • calendar = "standard"

xcdat is able to decode these time coordinates, but xarray cannot write the dataset to a file

Writing out time coordinates with "months since ..."

Result:

File ~/miniconda3/envs/xcdat_dev/lib/python3.10/site-packages/xarray/coding/times.py:684, in CFDatetimeCoder.encode(self, variable, name)
...
File src/cftime/_cftime.pyx:245, in cftime._cftime.date2num()

File src/cftime/_cftime.pyx:98, in cftime._cftime._dateparse()

ValueError: 'months since' units only allowed for '360_day' calendar

Writing out time coordinates with "years since ..."

Result:

File ~/miniconda3/envs/xcdat_dev/lib/python3.10/site-packages/xarray/coding/times.py:684, in CFDatetimeCoder.encode(self, variable, name)
...
File src/cftime/_cftime.pyx:245, in cftime._cftime.date2num()

File src/cftime/_cftime.pyx:102, in cftime._cftime._dateparse()

ValueError: In general, units must be one of 'microseconds', 'milliseconds', 'seconds', 'minutes', 'hours', or 'days' (or select abbreviated versions of these).  For the '360_day' calendar, 'months' can also be used, or for the 'noleap' calendar 'common_years' can also be used. Got 'years' instead, which are not recognized.

What did you expect to happen?

Since xcdat supports decoding non-CF time coordinates, we should be able to write them back to a file.

Minimal Complete Verifiable Example

import xcdat as xc
from tests.fixtures import generate_dataset

# Case 1 -- "months since ..."
# ---------------------------
ds1 = generate_dataset(decode_times=True, cf_compliant=False, has_bounds=True)

print(ds1.time.encoding) 
# {'calendar': 'standard', 'units': 'months since 2000-01-01'}

ds1.to_netcdf("qa/issue-396-decode-times/case2-non-cf-time.nc")
# ValueError: 'months since' units only allowed for '360_day' calendar

# Case 2 -- "years since ..."
# ---------------------------
ds2 = generate_dataset(decode_times=True, cf_compliant=False, has_bounds=True)

ds2.time.encoding["units"] = "years since 2000-01-01"
print(ds2.time.encoding) 
# {'calendar': 'standard', 'units': 'years since 2000-01-01'}

ds2.to_netcdf("qa/issue-396-decode-times/case2-non-cf-time.nc")
# ValueError: In general, units must be one of 'microseconds', 'milliseconds', 'seconds', 
# 'minutes', 'hours', or 'days' (or select abbreviated versions of these).  For the '360_day'
# calendar, 'months' can also be used, or for the 'noleap' calendar 'common_years' can also be 
# used. Got 'years' instead, which are not recognized.

Relevant log output

No response

Anything else we need to know?

Related issues

Potential Solutions

Environment

Latest main and xcdat=0.4.0

@tomvothecoder tomvothecoder added the type: bug Inconsistencies or issues which will cause an issue or problem for users or implementors. label Jan 5, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: bug Inconsistencies or issues which will cause an issue or problem for users or implementors.
Projects
Status: Todo
Development

No branches or pull requests

1 participant