How to convert cftime to unix timestamp?

53 Views Asked by At

I am looking for some convenient way to convert time in cftime format available in netcdf files to unix timestamp(ms), what is a suitable way to do this without several for loops, of extracting date and time string followed by datetime type conversion in python, and few other steps to finally get to unix timestamp(ms). While working with array of time values, it's really daunting to use several for loops to seemingly simple operation.

If there is any library or functionality available within cftime or datetime module, i would highly appreciate.

Here is the output of my initial data in cftime format:

<xarray.DataArray 'time' (time: 227)>
array([ 107. ,  129.5,  227.5, ..., 7928. , 7958.5, 7989. ], dtype=float32)
Coordinates:
  * time     (time) float32 107.0 129.5 227.5 ... 7.928e+03 7.958e+03 7.989e+03
Attributes:
bounds:         time_bounds
calendar:       gregorian
axis:           T
standard_name:  Time
long_name:      Time
Units:          days since 2002-01-01T00:00:00

When I used xarray.decode_cf(dataset), the array is shown but it is still random, and I am not able to figure out what these numbers mean.

Here is a sample array after xarray.decode_cf() operation:

[107. 129.5 227.5 258. 288.5 319. 349.5 380.5 410. 439.5 470. 495.5 561.5 592.5]

1

There are 1 best solutions below

0
FObersteiner On

Illustrating my comment,

import xarray as xr

# note that "units" must not me title-case:
attrs = {"units": "days since 2002-01-01T00:00:00"}
ds = xr.Dataset({"time": ("time", [107. ,  129.5,  227.5, 7928. , 7958.5, 7989.0], attrs)})

# now we have datetime:
xr.decode_cf(ds)
<xarray.Dataset>
Dimensions:  (time: 6)
Coordinates:
  * time     (time) datetime64[ns] 2002-04-18 2002-05-10T12:00:00 ... 2023-11-16
Data variables:
    *empty*

xr.decode_cf(ds).time
<xarray.DataArray 'time' (time: 6)>
array(['2002-04-18T00:00:00.000000000', '2002-05-10T12:00:00.000000000',
       '2002-08-16T12:00:00.000000000', '2023-09-16T00:00:00.000000000',
       '2023-10-16T12:00:00.000000000', '2023-11-16T00:00:00.000000000'],
      dtype='datetime64[ns]')
Coordinates:
  * time     (time) datetime64[ns] 2002-04-18 2002-05-10T12:00:00 ... 2023-11-16

# to get Unix time in ms, we can convert to integer, giving us Unix time in 
# nanoseconds, then divide by 1e6 to get milliseconds:
xr.decode_cf(ds).time.astype(int)//1_000_000
<xarray.DataArray 'time' (time: 6)>
array([1019088000000, 1021032000000, 1029499200000, 1694822400000,
       1697457600000, 1700092800000])
Coordinates:
  * time     (time) datetime64[ns] 2002-04-18 2002-05-10T12:00:00 ... 2023-11-16