Re: how does NCL (netCDF?) deal with time?

From: Jonathan Vigh <vigh_at_nyahnyahspammersnyahnyah>
Date: Thu, 28 Aug 2008 22:03:01 +0000

Hi Leslie,
   There are all sorts of ways to deal with time/date in NCL. There are
a number of user-contributed routines which use floating point years,
etc. But another approach (which I personally like the best for time
resolutions down to 1-sec) is to use integer seconds since a basetime.
This is how UNIX keeps track of time (a base time of 1970-01-01 00:00:00
UTC is used). NCL incorporates the udunits package, so there is a very
handy and efficient conversion function (ut_inv_calendar) to go between
"seconds since basetime" and a formatted date/time string. The downside
to this approach is that NCL's 32-bit integer type is +/- 2.147483e+09,
or about +/- 68 years from your basetime. So this limits the range of
times that can be represented using this method. If you use 1970, then
this "Y2K"-like problem would occur in the year 2037.

Anyway, here's an example procedure which takes arrays of formatted
strings of date/time and converts to an array of seconds since 1970.

Enjoy!
   Jonathan

;********************************************************
; Procedure: create_time_coordinate
;
; This procedure creates a general time coordinate which
; corresponds to the date/time strings provided as inputs.
; Several types of time information are output.
;
; The main input is Sdatetime, a string which contains the
; full date and time information with timezone:
; example: "04/14/2008 17:30:22 UTC"
; *123456789*123456789*12
; 0 10 20
;********************************************************
undef("create_time_coordinate")
procedure create_time_coordinate(Sdatetime[*]:string, \ % input
                                time_offset[*]:integer, \ %
output
                         start_time[*]:integer, \
                         end_time[*]:integer)
            
local
ntime,tChr,Stime,Sdate,start_datetime_Chr,end_datetime_Chr,month,day,year,hour,
\
      minute,second,base_time_offset_units,Stimezone

begin

  ntime = dimsizes(Sdatetime)

  tChr = stringtochar(Sdatetime)

; read in the first column, then form a date/time integer time
coordinate from this
; Stime = chartostring(tChr(:,11:18))
; Sdate = chartostring(tChr(:,0:9))
  Stimezone = chartostring(tChr(:,20:22))

; first make sure we're using UTC
  do it = 0, ntime-1
     if (Stimezone(it) .ne. "UTC") then
        print("WARNING: the code assumes we're using UTC and can't
handle non-UTC times.")
     end if
  end do

; do it = 0, ntime-1
; Sdatetime(it) = Sdate(it) + " " + Stime(it) + "UTC"
; end do
    
  start_datetime_Chr = stringtochar(Sdatetime(0))
 
  start_time(0) =
stringtointeger(chartostring(start_datetime_Chr(6:9))) ; 4-digit year
  start_time(1) =
stringtointeger(chartostring(start_datetime_Chr(0:1))) ; 2-digit month
  start_time(2) =
stringtointeger(chartostring(start_datetime_Chr(3:4))) ; 2-digit day
  start_time(3) =
stringtointeger(chartostring(start_datetime_Chr(11:12))) ; 2-digit hour
  start_time(4) =
stringtointeger(chartostring(start_datetime_Chr(14:15))) ; 2-digit minute
  start_time(5) =
stringtointeger(chartostring(start_datetime_Chr(17:18))) ; 2-digit second

  end_datetime_Chr = stringtochar(Sdatetime(ntime-1))

  end_time(0) = stringtointeger(chartostring(end_datetime_Chr(6:9)))
   ; 4-digit year
  end_time(1) =
stringtointeger(chartostring(end_datetime_Chr(0:1))) ; 2-digit month
  end_time(2) = stringtointeger(chartostring(end_datetime_Chr(3:4)))
   ; 2-digit day
  end_time(3) =
stringtointeger(chartostring(end_datetime_Chr(11:12))) ; 2-digit hour
  end_time(4) =
stringtointeger(chartostring(end_datetime_Chr(14:15))) ; 2-digit minute
  end_time(5) =
stringtointeger(chartostring(end_datetime_Chr(17:18))) ; 2-digit second
         
     
; One way to create an integer time coordinate would be to use the Unix
system command date
; which will produce the integer seconds since 01/01/1970 00:00:00 UTC.
Note that this
; time method will experience a 'Y2K'-type of problem in 2037 because
the size of a 32-bit integer
; can only span +/- ( 2.147483e+09 ). Obviously, one can only go back to
the year 1902 as well.

; it's much faster to use the udunits routine ut_inv_calendar
  month = stringtointeger(chartostring(tChr(:,0:1)))
  day = stringtointeger(chartostring(tChr(:,3:4)))
  year = stringtointeger(chartostring(tChr(:,6:9)))
  hour = stringtointeger(chartostring(tChr(:,11:12)))
  minute = stringtointeger(chartostring(tChr(:,14:15)))
  second = stringtointeger(chartostring(tChr(:,17:18)))

  base_time_offset_units = "seconds since 1970-01-01 00:00:00.0 UTC"
  time_offset =
doubletointeger(ut_inv_calendar(year,month,day,hour,minute,second,base_time_offset_units,0))
 
  time_offset_at_units = base_time_offset_units
   
  end do
  
end

Leslie Hartten wrote:

> I am just starting to work with both NCL and some new ascii
> datasets. The data have sub-daily resolution (e.g. 2-minute,
> 30-minute, or hourly) and are written with date & time in a decimal
> day-of-year format (e.g. the timestamps from 26 May 2006 are
> 147.00000, 147.02083, 147.04167, 147.06250, etc.). I want to have
> latitude, longitude, and date/time be the coordinate variables for the
> geophysical data in the files. I can very easily reformat the
> datasets before I start using them in NCL; I'm just not sure what form
> I should put them in. I've read every bit of NCL date/time related
> material I could find (including the udunits documentation at unidata)
> and I'm no less confused. I'm hoping someone on the list can help.
>
> Q1: how does NCL store time (date and time of day)?
>
> Q2: is there a date/time format I can use that will enable me to make
> a plot of 1 day's worth of geophysical data and another plot of 2
> weeks worth, for which NCL will be able to create a human-readable
> time axis? (In other words, labelled with hours in the first case and
> with Gregorian calendar days in the second case.)
>
> Q3: has anybody done anything like this and found it to be an
> especially good or an especially bad solution?
>
> Cheers,
> Leslie
> --
> Dr. Leslie M. Hartten
> CIRES, Univ. of Colorado email: Leslie.M.Hartten_at_noaa.gov
> 216 UCB web: http://cires.colorado.edu/~hartten
> Boulder CO 80309-0216 phone: (303)497-7052 fax: 497-6181
> --
> Disclaimer: The contents of this message are mine personally and do
> not necessarily reflect any position of the Government of the United
> States of America, the National Oceanic and Atmospheric
> Administration, or the University of Colorado.
> _______________________________________________
> ncl-talk mailing list
> ncl-talk_at_ucar.edu
> http://mailman.ucar.edu/mailman/listinfo/ncl-talk

_______________________________________________
ncl-talk mailing list
ncl-talk_at_ucar.edu
http://mailman.ucar.edu/mailman/listinfo/ncl-talk
Received on Thu Aug 28 2008 - 16:03:01 MDT

This archive was generated by hypermail 2.2.0 : Fri Aug 29 2008 - 07:39:21 MDT