Home > Net >  transform timestamp (Seconds sins 1.1.1904) from NetCDF file
transform timestamp (Seconds sins 1.1.1904) from NetCDF file

Time:05-09

even there are several posts concerning NetCDF files and timestamp conversion I draw a blank today.

I read in a NetCDF data set (version 3), and after I call variables information:

# Load required Python packages
import netCDF4 as nc
import matplotlib.pyplot as plt
from datetime import datetime, timedelta
import pandas as pd

#read in a NetCDF data set
ds = nc.Dataset(fn)

# call time variable information
print(ds['time'])

As answer I get:

<class 'netCDF4._netCDF4.Variable'>
float64 time(time)
    units: seconds since 1904-01-01 00:00:00.000 00:00
    long_name: time UTC
    axis: T
unlimited dimensions: time
current shape = (5760,)
filling on, default _FillValue of 9.969209968386869e 36 used

Now I would like to transform the seconds since 1.1.1904 time stamp into a DD.MM.YYYY HH:MM:SS.sss format. (by the way: why is there a second 00:00 information included after the time stamp?)

(1) I tried:

t = ds['time'][:]
dtime = []
dtime = (pd.to_datetime(t, format='%d.%m.%Y %H:%M:%S.micros') - datetime(1904, 1, 1)).total_seconds()

And I get the error: pandas_libs\tslibs\strptime.pyx in pandas._libs.tslibs.strptime.array_strptime() time data '3730320000' does not match format '%d.%m.%Y %H:%M:%S' (match)

(2) I tried:

d = datetime.strptime("01-01-1904", "%m-%d-%Y")
dt = d   timedelta(seconds=(t))

I get the TypeError: unsupported type for timedelta seconds component: MaskedArray

(3) I tried

d = datetime.strptime("%m-%d-%Y", "01-01-1904")
dt = d   timedelta(seconds=(ds['time']))

And I get the answer: unsupported type for timedelta seconds component: netCDF4._netCDF4.Variable

Has somebody a clearer view on the solution than I have at the moment?

Thanks, Swawa

CodePudding user response:

The NetCDF4 python library has a method for this: num2date().
https://unidata.github.io/netcdf4-python/#num2date. No need for datetime module.
NetCDF4 variables contain metadata attributes which describe the variable as seen in the output to your print:

print(ds['time']) #In particular the time variable units attribute.

# t contains just the numeric values of the time in `seconds since 1904-01-01 00:00:00.000 00:00`

t = ds['time'][:]
dtime = []
# t_var is the NetCDF4 variable which has the `units` attribute.
t_var = ds.['time']
#dtime = (pd.to_datetime(t, format='%d.%m.%Y %H:%M:%S.micros') - datetime(1904, 1, 1)).total_seconds()
dtime = NetCDF4.num2date(t, t_var.units)

The above should give you all the times in the dtime list as datetime objects.

print(dtime[0].isoformat())
print(dtime[-1].isoformat())

A simpler way would be:

dtime = NetCDF4.num2date(ds['time'][:], ds['time].units)

  • Related