Incorrect date/time conversion when reading netcdf file

280 Views Asked by At

I have a netcdf file (nc.in) containing 30 years of 3-hourly temperature data from 1981-2010. When I convert time to the gregorian calendar the resulting dates are incorrect. The output starts on 02/13/04 (should be 01/01/1981) and then skips three days each time rather than three hours, e.g. 01/13/04, then 02/16/04 etc. instead of 01/01/1981 00:00, then 01/01/1981 03:00 etc.

I used the following code to get time:

# Get time
nc.t <- ncvar_get(nc.in,"time")
nc.tunits <- ncatt_get(nc.in,"time","units")

and then converted it to Gregorian dates using:

# Split the time units string into fields
nc.tustr <- strsplit(nc.tunits$value, " ")
nc.tdstr <- strsplit(unlist(nc.tustr)[3], "-")
nc.tyear = as.integer(unlist(nc.tdstr)[1])
nc.tmonth = as.integer(unlist(nc.tdstr)[2])
nc.tday = as.integer(unlist(nc.tdstr)[3])
nc.chron=chron(nc.t, origin = c(nc.tyear, nc.tmonth, nc.tday))

See below for reproducibility. Sorry if this is not the correct info to provide - I am still learning how to provide reproducible examples.

dput(nc.in[1:10])
list(filename = "ERA5-STP-RUS-t2m.nc", writable = FALSE, id = 65536L, 
   safemode = FALSE, format = "NC_FORMAT_64BIT", is_GMT = FALSE, 
   groups = list(structure(list(id = 65536L, name = "", ndims = 3L, 
       nvars = 4L, natts = 2L, dimid = structure(0:2, .Dim = 3L), 
       fqgn = ""), class = "ncgroup4")), fqgn2Rindex = structure(list(
       1L), .Names = ""), ndims = 3, natts = 2)

dput(nc.t[1:10])
structure(c(710040L, 710043L, 710046L, 710049L, 710052L, 710055L, 
710058L, 710061L, 710064L, 710067L), .Dim = 10L)

dput(nc.tunits[1:10])
structure(list(TRUE, "hours since 1900-01-01 00:00:00.0", NULL, 
NULL, NULL, NULL, NULL, NULL, NULL, NULL), .Names = c("hasatt", 
"value", NA, NA, NA, NA, NA, NA, NA, NA))

dput(nc.chron[1:10])
structure(c(710040L, 710043L, 710046L, 710049L, 710052L, 710055L, 
710058L, 710061L, 710064L, 710067L), .Dim = 10L, format = "m/d/y", origin = c(1900L, 
1L, 1L), class = c("dates", "times"))
2

There are 2 best solutions below

0
On

ERA5 files are formatted using the CF Metadata Conventions. You can use package CFtime to deal with the time dimension of the data:

library(CFtime)

nc.t <- CFtime(nc.in$dim$time$units, nc.in$dime$time$calendar, nc.in$dim$time$vals)

You can also use the package to create factors for further processing.

0
On

Time in your ERA5 netCDF files is expressed in hours since 1900-01-01, while your code for chron expects to convert the number of days since 1900-01-01 into a date. Therefore you need to give to cron a time vector divided by 24, e.g.

nc.chron=chron(nc.t / 24, origin = c(nc.tyear, nc.tmonth, nc.tday))