@@ -236,20 +236,19 @@ def encode(self, variable: Variable, name: T_Name = None):
236
236
f"Variable { name !r} has conflicting _FillValue ({ fv } ) and missing_value ({ mv } ). Cannot encode data."
237
237
)
238
238
239
+ # cast to correct dtype in case of times
240
+ # see GH 7817
241
+ units = attrs .get ("units" , None )
242
+ if isinstance (units , str ) and "since" in units :
243
+ encoded_dtype = encoding .pop ("dtype" )
244
+ if encoded_dtype is not None and encoded_dtype != data .dtype :
245
+ data = np .asarray (data , dtype = encoded_dtype )
246
+
239
247
if fv_exists :
240
248
# Ensure _FillValue is cast to same dtype as data's
241
249
encoding ["_FillValue" ] = dtype .type (fv )
242
250
fill_value = pop_to (encoding , attrs , "_FillValue" , name = name )
243
- # retrieve _FillValue in case of np.datetime64
244
- # see GH 7817
245
- if np .issubdtype (data .dtype , np .datetime64 ):
246
- units = encoding .get ("units" , None )
247
- if isinstance (units , str ) and "since" in units :
248
- delta , _ = times ._unpack_netcdf_time_units (units )
249
- delta = times ._netcdf_to_numpy_timeunit (delta )
250
- fill_value = np .datetime64 (fill_value .item (), delta ).astype (
251
- "datetime64[ns]"
252
- )
251
+
253
252
if not pd .isnull (fill_value ):
254
253
data = duck_array_ops .fillna (data , fill_value )
255
254
@@ -284,19 +283,19 @@ def decode(self, variable: Variable, name: T_Name = None):
284
283
SerializationWarning ,
285
284
stacklevel = 3 ,
286
285
)
287
-
288
- dtype , decoded_fill_value = dtypes . maybe_promote ( data . dtype )
289
- # retrieve _FillValue in case of np.datetime64
290
- # see GH 7817
291
- if np . issubdtype ( data . dtype , np . datetime64 ) and decoded_fill_value . astype (
292
- np . int64
293
- ) == np .datetime64 ( "NaT" ). astype ( np .int64 ):
294
- delta , _ = times . _unpack_netcdf_time_units ( encoding [ "units" ])
295
- delta = times . _netcdf_to_numpy_timeunit ( delta )
296
- encoded_fill_values = {
297
- np . datetime64 ( encfill . item (), delta ). astype ( "datetime64[ns]" )
298
- for encfill in encoded_fill_values
299
- }
286
+ units = attrs . get ( "units" , None )
287
+ # try to cast to correct dtypes for data and fill_value
288
+ # GH 7817
289
+ if ((
290
+ isinstance ( units , str )
291
+ and "since" in units
292
+ and np .issubdtype ( data . dtype , np . integer )) or np . issubdtype ( data . dtype , np .datetime64 )
293
+ ):
294
+ dtype , decoded_fill_value = data . dtype , np . datetime64 ( "NaT" ). astype (
295
+ data . dtype
296
+ )
297
+ else :
298
+ dtype , decoded_fill_value = dtypes . maybe_promote ( data . dtype )
300
299
if encoded_fill_values :
301
300
transform = partial (
302
301
_apply_mask ,
0 commit comments