DATE

<< Click to Display Table of Contents >>

Navigation:  Gekko User Manual > Gekko statements >

DATE

Previous pageReturn to chapter overviewNext page

A Gekko date looks like for instance %= 2020q3;, note that date names always start with the symbol % (like the other scalars string and value). Dates are written like for instance 2020 (annual), 2020q3 (quarterly) or 2020m3d25 (daily) and can have frequency annual, quarterly, monthly, weekly, daily or undated. Dates are often used in combination with series variables, setting the periods over which these are calculated, printed, etc. See also the TIME statement.

 

Dates support adding or subtracting, for instance 2020q3+3 = 2021q2, or 2021q2-2020q3 = 3, etc.

 


 

Syntax

 

%d = expression;

date ?; //print string scalars

 

Note: You may use the non-mandatory date keyword to indicate date type (like date %x = %y + %z;).

 

Frequency

Examples

Notes

Annual

2020, 2020a

%= 2020; will set %d as a value, but it will still work fine as a date.

Quarterly

2020q3

4 quarters in each year.

Monthly

2020m3

12 months in each year.

Weekly

2020w3

Week numbering follows the ISO 8601 standard. This means that weeks around New Year are basically "strange" in the sense that the last days of particular year may belong to the first week of the subsequent year, and the first days of a particular year may belong to the last week of the preceding year (week number 52 or 53: the total number of weeks varies from year to year).

Daily

2020m3d25

Year-month-day.

Undated

30, 30u

Undated frequency can be used to create, for instance, a timeseries defined over different ages, so that x[30] corresponds to 30-year olds, etc. It could also represent hours measured from some starting point, or any other repetitive data.

 

There are a number of in-built date functions to compose and extract dates.

 

Date combining functions

 

Function name

Description

Examples

date(d, f, opt)

date(d, f)

Converts the date d into a new date with frequency f (string). The optional option can be omitted, or be 'start' or 'end'. Using 'start' or 'end' is only relevant when converting from a lower to a higher frequency.

 

Beware that week numbers are special around New Year.

 

Returns: date

%= 2021q1;
prt %d.date('a'); //2021

prt %d.date('m'); //error!
prt %d.date('m', 'start'); //2021m1
prt %d.date('m', 'end');   //2021m3
prt %d.date('w', 'start'); //2020w53 !!
prt %d.date('w', 'end');   //2021w13
//Note that the first week that fully 
//contains the first quarter of 2021 starts
//in 2020!

date(y, f, sub)

date(y, 'm', m, 'd', d)

Constructs a new quarterly/monthly/weekly date from year y (integer), frequency f (string), and subperiod sub (integer). You may also construct a daily date with a similar syntax.

 

Note: you may also use date(x), where x can be a value or a string, and Gekko will try to convert the argument into a date.

 

Returns: date

%= date(2020, 'q', 2);  //2020q2
%= date(2020, 'w', 42);  //2020w42
%= date(2020, 'm', 12, 'd', 24);  //2020m12d24

fromExcelDate(v)

Converts an Excel date (the value v, counting the number of days since January 1, 1900) to a date with daily frequency.

 

Returns: date (daily)

See examples regarding the toExcelDate() function.

getFreq(d)

Extracts the frequency of a date d.

Returns: string

%= 2020q2;
prt %d.getfreq();  //'q'

getDay(d)

Extracts the day number from a date d. Will fail if the date is not daily.

Returns: value (integer)

%= 2020m3d25;
prt %d.getday(); //25

getSpecialDay(year, name)

Finds a special day by year (value) and name (string), and returns its daily date. Mostly used for holidays. If you input a wrong name, Gekko will provide a link showing all possible special days. Current possible holiday names (English, and equivalent Danish names):

 

New_Years_Day            

Nytaarsdag

Leap_Day

Skuddag

Maundy_Thursday          

Skaertorsdag

Good_Friday              

Langfredag

Easter_Sunday            

Paaskedag

Easter_Monday            

Anden_paaskedag

Labour_Day              

Foerste_maj

General_Prayer_Day      

Store_bededag

Ascension_Day            

Kristi_himmelfartsdag

Whit_Sunday              

Pinsedag

Whit_Monday              

Anden_pinsedag

Constitution_Day        

Grundlovsdag

Christmas_Eve            

Juleaften

Christmas_Day            

Foerste_juledag

Boxing_Day              

Anden_juledag

New_Years_Eve            

Nytaarsaften

 

Note that getSpecialDay(%year, 'Leap_Day') may return a null value, else it returns February 29 in leap years. The leap day is not a holiday, but is nevertheless kept in this list of special days. See example.

prt 2021.getSpecialDay('Easter_Sunday'); //2021m4d4
prt 2021.getSpecialDay('Paaskedag');     //same day
 
for(val %year = 2021 to 2025);
  %day = %year.getSpecialDay('Christmas_Eve');
  %= %day.getWeekday('en');
  tell 'In {%year}, Christmas Eve is on a {%s}';
end;
//Result:
//In 2021, Christmas Eve is on a Friday
//In 2022, Christmas Eve is on a Saturday
//In 2023, Christmas Eve is on a Sunday
//In 2024, Christmas Eve is on a Tuesday
//In 2025, Christmas Eve is on a Wednesday
 
prt 2020.getSpecialDay('Leap_Day');
prt 2021.getSpecialDay('Leap_Day');
 
%= 2020;
if(not %y.getSpecialDay('Leap_Day').isNull());
  //code to handle if %y is a leap year
end;

getMonth(d)

getMonth(d, lang)

Extracts the month number from a date d. More specific than getSubPer(), and will fail if the date is not monthly or daily.

 

You may input a language lang ('en' = English, 'da' = Danish), in which case a string is returned.

 

Returns: value (integer) or string

%= 2020m2;
prt %d.getmonth();  //2
prt %d.getmonth('en');  //'February'
prt %d.getmonth('en').lower()[1..3]; //'feb'

getQuarter(d)

Extracts the quarter number from a date d. More specific than getSubPer(), and will fail if the date is not quarterly.

Returns: value (integer)

%= 2020q2;
prt %d.getquarter();  //2

getSubPer(d)

Extracts the sub-period from a date d (1 if annual or undated, the quarter if quarterly, the month if monthly or daily, and the week if weekly).

Returns: value (integer)

%= 2020q2;
prt %d.getsubper();  //2

getWeek(d)

Get the week number from a date d of weekly frequency. Does not accept daily frequency as argument, but the conversion date('w') can be used as intermediary for this (see examples). Beware that the year may change when converting from daily to weekly frequency.

Returns: value (integer)

%= 2020w20;
%d.getWeek(); //20
%d.getYear(); //2020
 
%= 2019m12d31;

%d.getWeek(); //error!
%d.date('w').getWeek(); //1
%d.date('w').getYear(); //2020!
 
%= 2021m1d1;
%d.date('w').getWeek(); //53
%d.date('w').getYear(); //2020!

getWeekday(d)

getWeekday(d, lang)

Extracts the weekday number from a date d. Will fail if the date is not daily. The numbers are as follows:

Monday = 1, Tuesday = 2, Wednesday = 3, Thursday = 4, Friday = 5, Saturday = 6, Sunday = 7.

 

You may input a language lang ('en' = English, 'da' = Danish), in which case a string is returned.

 

Returns: value (integer) or string.

%= 2020m3d25;
prt %d.getweekday();     //3
prt %d.getweekday('en'); //Wednesday
prt %d.getweekday('en').lower()[1..3]; //wed
prt %d.getweekday('da'); //Onsdag

getYear(d)

Extracts the year from a date d.

Returns: value (integer)

%= 2020q2;
prt %d.getyear();  //2020

max(d1, d2, ... )

Finds the largest of any number of dates. (max() can also be used with value arguments).

Returns: date

prt max(2002q1, 2001q4);

min(d1, d2, ... )

Finds the smallest of any number of dates. (min() can also be used with value arguments).

Returns: date

prt min(2002q1, 2001q4);

observations(d1, d2)

Counts the number of observations (periods) between date d1 and date d2, with both start and end date included. The date difference using - is always the same as the number of observations minus 1.

prt observations(2020q2, 2023q3); //14
prt 2023q3 - 2020q2;              //13

toExcelDate(d)

Converts a daily date d into an Excel date (counting the number of days since January 1, 1900). See also fromExcelDate(). Excel dates can be subtracted to obtain day spans.

 

Returns: value.

%v1 = toExcelDate(2019m11d12);
%v2 = toExcelDate(2019m12d3);
prt %v1, %v2; //43781 and 43802
prt %v2 - %v1; //21 days (span)
%= fromExcelDate(%v1 + 100);
prt %d; //100 days from 2019m11d12

truncate(d1, d2)

Finds overlap between two different time periods. The period d1 to d2 is compared with the global time period (if no local period is indicated), or with the local time period (if such a period is indicated in the <...> fields). Use a local time period if you need to find the overlap between two arbitrary time windows.

 

Returns: a list of two elements, start and end date of the resulting period. If the two elements are both null, there is no overlap.

time 2010 2020;
#= truncate(2000, 2030);  //(2010, 2020)
#= truncate(2000, 2015);  //(2010, 2015)
#= truncate(2000, 2005);  //(null, null)
time 1980 1990;
#= truncate(<2010 2020>, 2000, 2030);  //(2010, 2020)
#= truncate(<2010 2020>, 2000, 2015);  //(2010, 2015)
#= truncate(<2010 2020>, 2000, 2005);  //(null, null)

//

// The overlapping period (z) can be visualized as

// the overlap of these time windows/periods:     

//                                                

// period1    . x x x x x . . .                   

// period2    . . . y y y y y .                   

// truncate() . . . z z z . . .                   

 

 

 


 

Examples

 

Note that you may use expressions in the option field, when referring to dates. For instance (%per1 and %per2 are two dates):

 

prt <%per1-%per1+1> fY;

 

You may wish to use dates to control the flow of your system of program files, centralizing the assignment of dates in one place.

 

global:%per1 = 2012;  //will actually become a value, not a date
global:%per2 = 2040;
read bank2;
x2 <%per1 %per1> += 1000;  //only 1 year
sim <%per1 %per2>;
mulprt <%per1-%per2> y2;

 

Note here the use of the Global databank for storing the two dates. The contents of the Global databank 'survives' READ statements, and is practical for storage of general settings like such dates. Conversions are possible:

 

%s1 = '2010'; //string
%v1 = 2015; //value
%d1 = date(%s1);
%d2 = date(%v1);
time %d1 %d2;

 

Note that in order to convert the string %s1, you need an explicit conversion with the date() function (on the contrary, the conversion from the value %v1 is automatic even if omitted). The conversion will fail if not possible, for instance the string '201x' or the value 2015.4).

 

You may convert a date into a val like this:

 

time 1990 2012;
data = m(); //initializing
for date %= 1990 to 2012;
  data[%d] = val(%d) - 2000;
end;
prt data;

 

This will not work without the val() function. The result is this (for the last three years):

 

//                 data
//  2010        10.0000
//  2011        11.0000
//  2012        12.0000

 

You may subtract two dates or add/subtract an integer to a date (for daily dates, possible February 29 leap days are included):

 

prt 2020m2d28 - 1, 2020m2d28 + 1;        //2020m2d27, 2020m2d29
prt 2020m3d1 - 2020m2d27;                //3
prt observations(2020m2d27, 2020m3d1);   //4

 

The date difference using - is always the same as the number of observations minus 1.

 


 

Note

 

See the page with syntax diagrams if the basics of names, expressions, etc. is confusing.

 

If you need to convert a value or string scalar into a date type, use the date() conversion function.

 

Regarding variable types and the Gekko type system, see the VAR section. In this appendix, variable assignment rules, including variable types, is explained in more detail.

 


 

Related statements

 

FOR, MEM, STRING, TIME, VAL