Project

General

Profile

from numerical time to date; reproduce result of cdo showdate or showtimestamp

Added by Christopher Danek almost 2 years ago

Hi cdo team

I am trying to reproduce the result of cdo showdate or cdo showtimestamp on my own to learn something. Please see the attached monthly time series example file.

The time dim is

dimensions:
        time = UNLIMITED ; // (1980 currently)
variables:
        double time(time) ;
                time:standard_name = "time" ;
                time:bounds = "time_bnds" ;
                time:units = "days since 0001-01-01 00:00:00" ;
                time:calendar = "365_day" ;
                time:axis = "T" ;

and its numerical values are (ncdump -c)
 time = 674899.541666667, 674929, 674958.5, 674989, 675019.5, 675050, 
    675080.5, 675111.5, 675142, 675172.5, 675203, 675233.5, 675264.5, 675294, 
    675323.5, 675354, 675384.5, 675415, 675445.5, 675476.5, 675507, 675537.5, 
    675568, 675598.5, 675629.5, 675659, 675688.5, 675719, 675749.5, 675780, 
    ...

or (ncdump -ct)
 time = "1850-01-15 13", "1850-02-14", "1850-03-15 12", "1850-04-15", 
    "1850-05-15 12", "1850-06-15", "1850-07-15 12", "1850-08-15 12", 
    "1850-09-15", "1850-10-15 12", "1850-11-15", "1850-12-15 12", 
    "1851-01-15 12", "1851-02-14", "1851-03-15 12", "1851-04-15", 
    "1851-05-15 12", "1851-06-15", "1851-07-15 12", "1851-08-15 12", 
    "1851-09-15", "1851-10-15 12", "1851-11-15", "1851-12-15 12",
    ...

Of course, cdo showtimestamp yields the same dates:
  1850-01-15T13:00:00  1850-02-14T00:00:00  1850-03-15T12:00:00  1850-04-15T00:00:00
  1850-05-15T12:00:00  1850-06-15T00:00:00  1850-07-15T12:00:00  1850-08-15T12:00:00
  1850-09-15T00:00:00  1850-10-15T12:00:00  1850-11-15T00:00:00  1850-12-15T12:00:00
  1851-01-15T12:00:00  1851-02-14T00:00:00  1851-03-15T12:00:00  1851-04-15T00:00:00
  1851-05-15T12:00:00  1851-06-15T00:00:00  1851-07-15T12:00:00  1851-08-15T12:00:00
  ...

Here is what I am doing with the numerical values (i.e. the days since year 1):

if calendar is non-leap (here: day_365, i.e. a non-leap calendar):
> for all years:
> > if current year is leap year: 
> > > add one day to all timepoints after Feb28 of the current leap year and all following timepoints until the end of the time series
> if origin year (here: 1) and first year (here: 1850) differ:
> > add one day for every Feb29 between those years minus 1 (here: 448 - 1 = 447)

This is my result (column "own"):

                     own                 cdo  dt_day      dt_sec
...
25   1852-01-15 12:00:00 1852-01-15 12:00:00  0 days      0 secs
26   1852-02-14 00:00:00 1852-02-14 00:00:00  0 days      0 secs
27   1852-03-14 12:00:00 1852-03-15 12:00:00 -1 days -86400 secs
28   1852-04-14 00:00:00 1852-04-15 00:00:00 -1 days -86400 secs
29   1852-05-14 12:00:00 1852-05-15 12:00:00 -1 days -86400 secs
30   1852-06-14 00:00:00 1852-06-15 00:00:00 -1 days -86400 secs
31   1852-07-14 12:00:00 1852-07-15 12:00:00 -1 days -86400 secs
32   1852-08-14 12:00:00 1852-08-15 12:00:00 -1 days -86400 secs
33   1852-09-14 00:00:00 1852-09-15 00:00:00 -1 days -86400 secs
34   1852-10-14 12:00:00 1852-10-15 12:00:00 -1 days -86400 secs
35   1852-11-14 00:00:00 1852-11-15 00:00:00 -1 days -86400 secs
36   1852-12-14 12:00:00 1852-12-15 12:00:00 -1 days -86400 secs
37   1853-01-14 12:00:00 1853-01-15 12:00:00 -1 days -86400 secs
38   1853-02-13 00:00:00 1853-02-14 00:00:00 -1 days -86400 secs
39   1853-03-14 12:00:00 1853-03-15 12:00:00 -1 days -86400 secs
40   1853-04-14 00:00:00 1853-04-15 00:00:00 -1 days -86400 secs
41   1853-05-14 12:00:00 1853-05-15 12:00:00 -1 days -86400 secs
42   1853-06-15 00:00:00 1853-06-15 00:00:00  0 days      0 secs
43   1853-07-15 12:00:00 1853-07-15 12:00:00  0 days      0 secs
...
1945 2012-01-15 12:00:00 2012-01-15 12:00:00  0 days      0 secs
1946 2012-02-14 00:00:00 2012-02-14 00:00:00  0 days      0 secs
1947 2012-03-14 12:00:00 2012-03-15 12:00:00 -1 days -86400 secs
1948 2012-04-14 00:00:00 2012-04-15 00:00:00 -1 days -86400 secs
1949 2012-05-14 12:00:00 2012-05-15 12:00:00 -1 days -86400 secs
1950 2012-06-14 00:00:00 2012-06-15 00:00:00 -1 days -86400 secs
1951 2012-07-14 12:00:00 2012-07-15 12:00:00 -1 days -86400 secs
1952 2012-08-14 12:00:00 2012-08-15 12:00:00 -1 days -86400 secs
1953 2012-09-14 00:00:00 2012-09-15 00:00:00 -1 days -86400 secs
1954 2012-10-14 12:00:00 2012-10-15 12:00:00 -1 days -86400 secs
1955 2012-11-14 00:00:00 2012-11-15 00:00:00 -1 days -86400 secs
1956 2012-12-14 12:00:00 2012-12-15 12:00:00 -1 days -86400 secs
1957 2013-01-14 12:00:00 2013-01-15 12:00:00 -1 days -86400 secs
1958 2013-02-13 00:00:00 2013-02-14 00:00:00 -1 days -86400 secs
1959 2013-03-14 12:00:00 2013-03-15 12:00:00 -1 days -86400 secs
1960 2013-04-14 00:00:00 2013-04-15 00:00:00 -1 days -86400 secs
1961 2013-05-14 12:00:00 2013-05-15 12:00:00 -1 days -86400 secs
1962 2013-06-15 00:00:00 2013-06-15 00:00:00  0 days      0 secs
1963 2013-07-15 12:00:00 2013-07-15 12:00:00  0 days      0 secs
...

As you can see, for non-leap years I obtain the same as cdo.

For leap-years I miss a constant offset of 1 day. The solution would be to add this day to all leap years. But: The offset is needed not only at all timepoints after Feb28 of a leap year (here: the monthly timepoints March to December of the leap year), but also at the first 5 timepoints of the year following the leap year (here: the monthly timepoints from January to May after the leap year).

How does cdo handle this? What am I missing? Thanks a lot for any hint!
Kind regards,
Chris

ps: What is not covered here: if the calendar is e.g. 360_day, the missing 5 days per year must be added to the numerical values as well.


Replies (1)

RE: from numerical time to date; reproduce result of cdo showdate or showtimestamp - Added by Ralf Mueller almost 2 years ago

hi!

your calendar is only "365 day". There is not leap year in the data. Maybe that's why your computation differs from what CDO and ncdump are representing.

cheers
ralf

    (1-1/1)