Coder for CF Datetime coding. Parameters ---------- use_cftime : bool, optional Only relevant if encoded dates come from a standard calendar (e.g. "gregorian", "proleptic_gregorian", "standard", or not specified). If None (default), attempt to decode times to
| 1353 | |
| 1354 | |
| 1355 | class CFDatetimeCoder(VariableCoder): |
| 1356 | """Coder for CF Datetime coding. |
| 1357 | |
| 1358 | Parameters |
| 1359 | ---------- |
| 1360 | use_cftime : bool, optional |
| 1361 | Only relevant if encoded dates come from a standard calendar |
| 1362 | (e.g. "gregorian", "proleptic_gregorian", "standard", or not |
| 1363 | specified). If None (default), attempt to decode times to |
| 1364 | ``np.datetime64`` objects; if this is not possible, decode times to |
| 1365 | ``cftime.datetime`` objects. If True, always decode times to |
| 1366 | ``cftime.datetime`` objects, regardless of whether or not they can be |
| 1367 | represented using ``np.datetime64`` objects. If False, always |
| 1368 | decode times to ``np.datetime64`` objects; if this is not possible |
| 1369 | raise an error. |
| 1370 | May not be supported by all the backends. |
| 1371 | time_unit : PDDatetimeUnitOptions |
| 1372 | Target resolution when decoding dates. Defaults to "ns". |
| 1373 | """ |
| 1374 | |
| 1375 | def __init__( |
| 1376 | self, |
| 1377 | use_cftime: bool | None = None, |
| 1378 | time_unit: PDDatetimeUnitOptions = "ns", |
| 1379 | ) -> None: |
| 1380 | self.use_cftime = use_cftime |
| 1381 | self.time_unit = time_unit |
| 1382 | |
| 1383 | def encode(self, variable: Variable, name: T_Name = None) -> Variable: |
| 1384 | if np.issubdtype(variable.dtype, np.datetime64) or contains_cftime_datetimes( |
| 1385 | variable |
| 1386 | ): |
| 1387 | dims, data, attrs, encoding = unpack_for_encoding(variable) |
| 1388 | |
| 1389 | units = encoding.pop("units", None) |
| 1390 | calendar = encoding.pop("calendar", None) |
| 1391 | dtype = encoding.get("dtype", None) |
| 1392 | |
| 1393 | # in the case of packed data we need to encode into |
| 1394 | # float first, the correct dtype will be established |
| 1395 | # via CFScaleOffsetCoder/CFMaskCoder |
| 1396 | if "add_offset" in encoding or "scale_factor" in encoding: |
| 1397 | dtype = data.dtype if data.dtype.kind == "f" else "float64" |
| 1398 | (data, units, calendar) = encode_cf_datetime(data, units, calendar, dtype) |
| 1399 | |
| 1400 | safe_setitem(attrs, "units", units, name=name) |
| 1401 | safe_setitem(attrs, "calendar", calendar, name=name) |
| 1402 | |
| 1403 | return Variable(dims, data, attrs, encoding, fastpath=True) |
| 1404 | else: |
| 1405 | return variable |
| 1406 | |
| 1407 | def decode(self, variable: Variable, name: T_Name = None) -> Variable: |
| 1408 | units = variable.attrs.get("units", None) |
| 1409 | if isinstance(units, str) and "since" in units: |
| 1410 | dims, data, attrs, encoding = unpack_for_decoding(variable) |
| 1411 | |
| 1412 | units = pop_to(attrs, encoding, "units") |
no outgoing calls
searching dependent graphs…