jdate.gms : Julian date test

Description

The gams function JDate(year,month,day) accepts arguments similar to
to date functions in other languages. The earliest date is Jan 1, 1, and
the latest date is Dec 31, 9999. Gams picked Jan 1, 1900 as day 1,
as done by Excel. Unfortunately, Excel treats the year 1900 incorrectly
as a leap year and the serial days starting with March 1, 1900 will
be off by one day.

The arguments are can be positive or negative and do not have to form
a proper date. The arguments with fractional values are first converted
to a signed integer by using the floor() function.

Note about Excel:
The Excel DATE(year,month,day) function has the following data ranges
note that excel incorrectly treats the year 1900 as a leap year.
 DATE(1900, 1, 1) =        1
 DATE(1900, 2,28) =       59
 DATE(1900, 3, 1) =       61 incorrect; should be 60
 DATE(9999,12,31) =  2958465 incorrected; should be 2958464
for years having a value of less than 1900, 1900 + year is assumed

The wiki at http://en.wikipedia.org/wiki/Julian_day defines the Julian date (JD)
as the interval of time in days and fractions of a day since
January 1, 4713 BC Greenwich noon. For example JD values are:
   Sunday January 14, 2007 at 13:18:59.9'  JD = 2454115.05486
The GAMS days start with 1/1/1900 00:00:00 which giveds an offset of 2415019.500

Keywords: GAMS language features, calendar functions, Julian calendar


Reference

  • GAMS Development Corporation, Formulation and Language Example.

Small Model of Type : GAMS


Category : GAMS Model library


Main file : jdate.gms

$title Julian Date Test (JDATE,SEQ=292)

$onText
The gams function JDate(year,month,day) accepts arguments similar to
to date functions in other languages. The earliest date is Jan 1, 1, and
the latest date is Dec 31, 9999. Gams picked Jan 1, 1900 as day 1,
as done by Excel. Unfortunately, Excel treats the year 1900 incorrectly
as a leap year and the serial days starting with March 1, 1900 will
be off by one day.

The arguments are can be positive or negative and do not have to form
a proper date. The arguments with fractional values are first converted
to a signed integer by using the floor() function.

Note about Excel:
The Excel DATE(year,month,day) function has the following data ranges
note that excel incorrectly treats the year 1900 as a leap year.
 DATE(1900, 1, 1) =        1
 DATE(1900, 2,28) =       59
 DATE(1900, 3, 1) =       61 incorrect; should be 60
 DATE(9999,12,31) =  2958465 incorrected; should be 2958464
for years having a value of less than 1900, 1900 + year is assumed

The wiki at http://en.wikipedia.org/wiki/Julian_day defines the Julian date (JD)
as the interval of time in days and fractions of a day since
January 1, 4713 BC Greenwich noon. For example JD values are:
   Sunday January 14, 2007 at 13:18:59.9'  JD = 2454115.05486
The GAMS days start with 1/1/1900 00:00:00 which giveds an offset of 2415019.500

Keywords: GAMS language features, calendar functions, Julian calendar
$offText

$eolCom //

Set i / 1*22 /;

Acronym error;

* The following table shows different ways of entering dates:
Table tvals(i,*) 'test values'
       year    month    day     excel   gams
    1  2005     10      20      38645
    2  2005.3   10.3    20.3    38645
    3  2005.7   10.7    20.7    38645
    4  2005     22      20      39010
    5  2005     22     300      39290
    6  2005     -5     300      38468
    7  2005     -5     -10      38158
    8  2005     -5     -10.3    38157
    9  2005     -5     -10.7    38157
   10     2     -9    -424          0   // excel 1900 0 1 must be wrong
   11  1900      1       1          1
   12     0      0       1      error
   13  2004      2      30      38047
   14  2004     14      30      38413
   15  2004      0       0      37955
   16  9999     12      31    2958465
   17  9999     13       1      error
   18  1900      1       2          2
   19  1899     12      31     693962   // excel 3799 12 31
   20  1899     12      30     693961   // excel 3799 12 30
   21  1900      2       1         32
   22     1      1       1        367   // excel 1901  1  1;

Parameter res(i) 'GAMS Julian serial numbers';

display tvals;

* The following will create three errors
res(i) = jdate(tvals(i,'year'),tvals(i,'month'),tvals(i,'day'));
abort$(execError <> 2) 'we should have had 2 errors when using tvals';
execError = 0;

tvals(i,'gams') = res(i);
display tvals;

* abort$(execError <> 2) 'we should have had 2 errors when using res';
* execError = 0;

* Now we will recover the date components
Parameter back(i,*) 'recovered date components';
back(i,'gams')  = res(i);
back(i,'year')  = gyear(res(i));
back(i,'month') = gmonth(res(i));
back(i,'day')   = gday(res(i));

* there will be errors
back(i,'new') = jdate(back(i,'year'),back(i,'month'),back(i,'day'));
abort$(execError <> 3) 'we should have had 3 errors when jdate with back';
execError = 0;

display back;

* GAMS and JD days example
Scalar
   JD         'Sunday January 14, 2007 at 13:18:59.9' / 2454115.05486 /
   offset     'days between the JD epoch and GAMS'    / 2415019.500   /
   gamsjulian 'GAMS Julian days'
   julian     'JD days adjusted to GAMS days';

Scalar year, month, day, dow, hours, minutes, seconds, millisecs;

gamsjulian = jdate(2007,1,14) + jtime(13,18,59.9);
julian     = JD - offset;
abort$round(gamsjulian - julian,5) 'julian day problems', jd, offset, gamsjulian, julian;

year      = gyear(gamsjulian);
month     = gmonth(gamsjulian);
day       = gday(gamsjulian);
dow       = gdow(gamsjulian);
hours     = ghour(gamsjulian);
minutes   = gminute(gamsjulian);
seconds   = gsecond(gamsjulian);
millisecs = gmillisec(gamsjulian);

display julian, offset, gamsjulian, dow, month, day, year, hours, minutes, seconds, millisecs;