1

I am working with a netcdf format code and I need to convert the time from seconds from the starting time (2016-01-01 00:00:00.0) to time in UTC. I'm fairly new to all of this so I am really struggling!

I have tried using the num2date from netCDF4.

from netCDF4 import date2num , num2date, Dataset
time=f.variables['time'][:]
dates=netCDF4.num2date(time[:],time.units)
print(dates.strftime('%Y%m%d%H') for date in dates)

AttributeError: 'MaskedArray' object has no attribute 'units'

FObersteiner
  • 22,500
  • 8
  • 42
  • 72
wam_salley
  • 33
  • 1
  • 8

1 Answers1

0

Since you extract time from the variables in time=f.variables['time'][:], it will lose it's associated unit (time is just a masked array, as the error says). What you have to feed to num2date() is variables['time'].units, e.g.

from netCDF4 import date2num, num2date, Dataset
file = ... # your nc file

with Dataset(file) as root:
    time = root.variables['time'][:]
    dates = num2date(time, root.variables['time'].units)
    ## directly get UTC hours here:
    # unit_utchours = root.variables['time'].units.replace('seconds', 'hours')
    ## would e.g. be 'hours since 2019-08-15 00:00:00'
    # utc_hours = date2num(dates, unit_utchours)

# check:
print(dates[0].strftime('%Y%m%d%H'))
# e.g. prints 2019081516

...to get the dates as a number, you could e.g. do

num_dates = [int(d.strftime('%Y%m%d%H')) for d in dates]
# replace int with float if you need floating point numbers etc.

...to get the dates in UTC hours, see the commented section in the first code block. Since the dates array contains objects of type datetime.datetime, you could also do

utc_hours = [d.hour+(d.minute/60)+(d.second/3600) for d in dates]
FObersteiner
  • 22,500
  • 8
  • 42
  • 72
  • just found a very similar question was already answered [here](https://stackoverflow.com/a/33989979/10197418). – FObersteiner Oct 01 '19 at 08:07
  • When I do that, I get this error 'KeyError: float64 time(time) standard_name: time units: seconds since 2016-01-01 00:00:00.0 UTC unlimited dimensions: time current shape = (103384,) filling on, default _FillValue of 9.969209968386869e+36 used' – wam_salley Oct 01 '19 at 14:23
  • which line throws the error? `time = ...` or `dates = ...`? if it's the second, you could try to use `time.data` – FObersteiner Oct 01 '19 at 14:47
  • its the time=… I think it might have to do with it being a float, but I really am not sure – wam_salley Oct 01 '19 at 14:50
  • hm... if it's really this line, the error should also be thrown in the version of the code you posted in the question (in `time=f.variables['time'][:]`). float format is fine btw. – FObersteiner Oct 01 '19 at 14:57
  • I got it to work, but its giving me very strange values when I plot it like 0001-01-18 when it should be 2016-07-18 at 16:39:41 – wam_salley Oct 01 '19 at 15:18
  • Sounds strange, but hard to tell without an example file. If you can share a file, I could have a look. – FObersteiner Oct 01 '19 at 20:00
  • I actually got it to work, however its only reading for one index, how do I get it to read for the entire array? – wam_salley Oct 02 '19 at 15:06
  • you mean `print(dates[0].strftime('%Y%m%d%H'))`? I just put this line there to see if the output is ok. it just prints `dates` at index 0. to print all lines, do e.g. `for d in dates: print(d.strftime('%Y%m%d%H'))` – FObersteiner Oct 02 '19 at 15:43
  • yes! I actually need the time in decimals in order to plot it right. – wam_salley Oct 02 '19 at 15:52
  • One last question, I need the data in the format (H+(M/60)+(seconds/3600)). How would i convert this into that? I want to get this figured out because this is only one of my data sets out of many to. I can do it "manually" but I don't want to do that everytime. – wam_salley Oct 02 '19 at 16:42
  • Also, you have been super helpful! – wam_salley Oct 02 '19 at 16:42
  • you mean utc hours? I've added two options how to get those to my answer. you could either get it using the `date2num` function from the netCDF package or run another list comprehension. I'd say `netcdf` is not the easiest data format to start working with, so I'm glad if I could help. Once you get used to it, it's a pretty neat format ;-) – FObersteiner Oct 02 '19 at 18:02