﻿id	summary	reporter	owner	description	type	status	priority	milestone	component	version	resolution	keywords	cc
771	VERY IMPORTANT Update:  Reference Time	arango		"ROMS support several date calendars according to the value of the input parameter '''TIME_REF''' in '''ocean.in''':

{{{
time_ref = -2            Truncated Julian day number (Julian/Gregorian)
                           'time-units since 1968-05-23 00:00:00'
                         origin: Jan 01, 4713 BC (Proleptic Julian Calendar)
                                 Nov 24, 4713 BC (Proleptic Gregorian Calendar)

time_ref = -1            360 day per year calendar
                           'time-units since 0000-12-30 00:00:00'
                         origin: Jan 1, 0000 (360_day Calendar)

time_ref = 0             Proleptic Gregorian calendar
                           'time-units since 0001-01-01 00:00:00'
                         origin: Jan 1, 0000 (Proletic gregorian Calendar)

time_ref = YYYYMMDD.dd   Gregorian or Proleptic Gregorian calendar
                           'time-units since YYYY-MM-DD hh:mm:ss'
                         origin: Jan 1, 0000 (Proletic gregorian Calendar)
}}}

Notice that a calendar obtained by extending backward in time from its invention or implementation is called the '''Proleptic''' version of the calendar. For example, the Proleptic Gregorian Calendar extends backward the date preceding '''15 October 1582''' (Gregorian Calendar start) with a year length of '''365.2425''' days.

Until now, the reference date has been used loosely in ROMS, and it is only crucial when using the '''360_day''' calendar.  However, from this update on, it will be used strictly to measure the elapsed time since the reference date.  It will not affect your current application configuration if the all the datasets have the same reference time coordinates.  For example, input NetCDF files usually have the '''units''' attribute of the form:
 {{{
       double ocean_time(ocean_time) ;
                ocean_time:long_name = ""time since initialization"" ;
                ocean_time:units = ""seconds since 1900-01-01 00:00:00"" ;
                ocean_time:calendar = ""gregorian"" ;
or

        double TIME(TIME) ;
                TIME:long_name = ""time of atmosphere forcing"" ;    
                TIME:units = ""days since 1900-01-01 00:00:00"" ;
                TIME:time_origin = ""01-JAN-1900 00:00:00"" ;
                TIME:standard_name = ""time"" ;
                TIME:calendar = ""gregorian"" ;
}}}
ROMS only process the '''units''' attribute for the time coordinate.

'''So why this change?'''

Because it allows input datasets to have different reference dates than the one specified in '''ocean.in''', provided that:

* All the datasets use the same calendar and have the same origin. Notice that '''time_ref = 0''' or '''time_ref > 0''' ('''YYYYMMDD.dd''') correspond to the Proleptic Gregorian Calendar and have the same origin (see above).  We cannot use datasets with both '''time_ref = -1''' and '''time_ref >= 0''' definitions because it have different origin and consequently non unique date numbers. Although they have the same calendar (Proleptic Gregorian) in the ROMS implementation.

* It covers the time range needed by the ROMS application.

* Users need to be strict about the '''units''' attribute when creating dataset NetCDF files.

So, there is '''no''' longer a need to modify the input dataset by recomputing the time coordinate to a particular time reference or epoch.  ROMS will adjust the data time variable internally to the desired epoch specified by '''time_ref''', hurrah!  I know, we all had to manipulate the time in the input dataset NetCDF files. It was very annoying.

Two new routines were added to '''mod_netcdf.F''' to read time for a dataset:
{{{
      INTERFACE netcdf_get_time
        MODULE PROCEDURE netcdf_get_time_0d
        MODULE PROCEDURE netcdf_get_time_1d
      END INTERFACE netcdf_get_time
}}}
For example, in '''get_3dfld.F''' we now have:

{{{
            CALL netcdf_get_time (ng, model, ncfile, Tname(ifield),     &
     &                            Rclock%DateNumber, Tval,              &
     &                            ncid = ncid,                          &
     &                            start = (/Trec/),                     &
     &                            total = (/1/))

instead of

            CALL netcdf_get_fvar (ng, model, ncfile, Tname(ifield),     &
     &                            Tval,                                 &
     &                            ncid = ncid,                          &
     &                            start = (/Trec/),                     &
     &                            total = (/1/))

}}}
Notice that '''netcdf_get_time''' has an additional argument ('''Rclock%!DateNumber''') when compared with the older call to '''netcdf_get_fvar'''.

As a consequence, several routines were modified to use '''netcdf_get_time''' for reading the dataset time.

The '''dateclock.F''' module was modified to absorb the new changes. The '''datenum''' and its inverse '''datevec''' routines now compute the serial date number and date vector, respectively, for all the calendars supported in ROMS.  Also, a new routine '''datestr''' was added to compute the date string from the serial date number.

----

'''Warningx:'''

* ROMS now supports several Julian Day Numbers ('''JDN''') with the '''time_ref = -2''' option, but I will discourage Users to use them because it can be confusing. Since '''JDN''' can be large, there are several variants according to the epoch:
 {{{
Reduced:     days since 1858-11-16 12:00:00   (offset = 2400000)
Modified:    days since 1858-11-17 00:00:00   (offset = 2400000.5)
Truncated:   days since 1968-05-23 12:00:00   (offset = 2440000.5)
}}}
 Check the following [https://en.wikipedia.org/wiki/Julian_day wikipedia link] for more information.

 The '''JDN''' is primarily used by astronomers. Although in the formal definition Julian days start and end at noon, in ROMS Julian days starts and end at midnight. So, it is '''12 hours faster'''. The Julian Calendar was adjusted on '''Oct 15, 1582''' (Gregorian Calendar start date) with a year length of 365.2425 days.  ROMS have the equations for both the Proleptic Julian Calendar which starts on '''Jan 1, 4713 BC''' or the corrected Proleptic Gregorian Calendar (default) which starts on '''Nov 24, 4713 BC'''.

 As you can see, it is confusing and ambiguous, and we should stay away from it.

* Also, it has been broad to my attention that several datasets out there have time clocks shifted by one or two days. It is wise to check the time coordinates always before using a dataset.  I will also release an update the Matlab scripts with the implementation of ROMS clocks.

----

We provide new Perl script '''dates''' in the '''ROMS/Bin''' directory that can be used for date manipulation containing the following functions:

* '''datenum:''' Converts Proleptic Gregorian Calendar date to serial date number. It is similar to Matlab's ''datenum'' function. If the date argument is omitted, today's date is used.

* '''daysdiff:''' Calculates the number of days between two dates.
      
* '''numdate:''' Converts serial date number to a date string. It is the inverse of '''datenum''' and similar to Matlab's ''datestr'' function.

* '''yday:''' Computes day-of-the-year given a date. If the date argument is omitted, today's date is used.

Many thanks to Dave Robertson for coding this Perl function.

Several '''dates_test''' scripts ('''.bash''', '''.ksh''', '''.sh''') are provided as examples for usage. In '''dates_test.bash''', we have:


{{{
today=`date +""%d-%m-%Y %r""`

dn1=`dates datenum`
ds1=`dates numdate $dn1`
yd1=`dates yday $ds1`

dn2=`dates datenum 1900-01-01`
ds2=`dates numdate $dn2`
yd2=`dates yday $ds2`
d21=`dates daysdiff $ds2 $ds1`

dn2=`dates datenum 19000101`
ds2=`dates numdate $dn2`
yd2=`dates yday $ds2`
d21=`dates daysdiff $ds2 $ds1`

dn3=`dates datenum 1968-05-23`
ds3=`dates numdate $dn3`
yd3=`dates yday $ds3`
d31=`dates daysdiff $ds3 $ds1`

echo
echo ""Testing 'dates' Perl Script on $today""
echo
echo ""Today's Date:               $ds1""
echo ""Today's Date Number:        $dn1""
echo ""Today's Day-of-the-year:    $yd1""
echo
echo ""Reference Date:             $ds2""
echo ""Reference Date Number:      $dn2""
echo ""Reference Day-of-the-year:  $yd2""
echo ""Days since Reference date:  $d21""
echo
echo ""Truncated Date:             $ds3""
echo ""Truncated Date Number:      $dn3""
echo ""Truncated Day-of-the-year:  $yd3""
echo ""Days since TRuncated date:  $d31""
echo
}}}
which yields:

{{{
Testing 'dates' Perl Script on 20-06-2018 05:18:12 PM

Today's Date:               2018-06-20
Today's Date Number:        737231
Today's Day-of-the-year:    171

Reference Date:             1900-01-01
Reference Date Number:      693962
Reference Day-of-the-year:  1
Days since Reference date:  43269

Truncated Date:             1968-05-23
Truncated Date Number:      718941
Truncated Day-of-the-year:  144
Days since TRuncated date:  18290
}}}
"	upgrade	new	major	Release ROMS/TOMS 3.7	Nonlinear	3.7			
