RPG and Dates
Date manipulation in RPG
RPG & SQL Date Operations
RPG can be used to manipulate dates, in various formats. With the inclusion of Built-In-Functions, calculating the day of the week, (1 for Monday) can be managed in just one line of code by using BIFs %REM AND %DIFF. (Note the example below.) Dates can easily be manuiplated adding or subtracting using %MONTHS and %DAYS, even %YEARS. Embedded SQL can add another avenue of date calculations to an RPG program.
In the sample code below the line of code, EXEC SQL SET :DIFFDATE = :DATE1 - :DATE2 returns the result to a data structure. Unlike the RPG date difference calculations, the SQL date manipulation returns the difference in days, months, and years. SQL also has a date fuction, DAYOFWEEK which will return the day of the week as a number (1,2,3, etc.).
Ctl-Opt Option( *NoDebugIO : *SrcStmt ) DftActGrp( *No )
ActGrp( 'DATE1' ) PgmInfo( *PCML : *Module )
Main(Main) BNDDIR('QC2LE':'SC0000_BD') ;
Dcl-Pr CEETREC extproc('CEETREC');
rc Int(10) const options(*omit) ;
user_rc Int(10) const options(*omit) ;
End-Pr;
Dcl-DS *n ;
DiffDate zoned(8:0) ;
DiffYears zoned(4:0) overlay(DiffDate) ;
DiffMonths zoned(2:0) overlay(DiffDate: *Next) ;
DiffDays zoned(2:0) overlay(DiffDate: *Next) ;
END-DS;
Dcl-S Today zoned(8:0) ;
Dcl-S NbrofDays packed(9:0) ;
Dcl-S NumDays packed(9:0) ;
Dcl-S weekDay int(10) ;
Dcl-S weekDay7 int(10) ;
Dcl-S dayOfWeek int(10) ;
Dcl-S dayOfWeek2 int(10) ;
Dcl-S dayOfYear int(10) ;
Dcl-S dateChar char(10) ;
Dcl-S dayName char(12) ;
Dcl-S Date1 date inz(d'2018-11-08') ;
Dcl-S Date2 date inz(*sys) ;
Dcl-S DtTmStamp timeStamp inz(*SYS) ;
Dcl-S firstDate date ;
Dcl-S lastDate date ;
Dcl-S baseDate date inz(*job) ;
Dcl-S daysIn zoned(2:0) inz(1) ;
Dcl-Proc Main ;
Dcl-PI *n extPgm('DATEDIFF') ;
endProgram char(1) const ;
END-PI ;
Exec SQL
set option
Commit = *None,
Naming = *Sys,
DECRESULT = (63, 63, 0),
datfmt = *ISO ;
Today = %dec(%date:*ISO) ;
firstDate = BaseDate - %days(%subdt(BaseDate:*d) - 1) +
%days(DaysIn - 1) ;
EXEC SQL
set :DiffDate = :Date1 - :Date2 ;
EXEC SQL
set :lastDate = last_day(:Date2) ;
EXEC SQL
set :DateChar = TO_CHAR(:DtTmStamp, 'MM-DD-YYYY') ;
EXEC SQL
set :DayName = dayName(:date2) ;
numDays = %Diff(Date1: Date2: *Days) ;
EXEC SQL set :dayOfWeek = dayOfWeek_ISO(:date2) ;
EXEC SQL set :dayOfWeek2 = dayOfWeek(:date2) ;
WeekDay = %rem(%diff(Date2:d'0001-01-01':*d) : 7) + 1 ;
WeekDay7= %rem(%diff(Date2:d'0001-01-07':*d) : 7) + 1 ;
EXEC SQL set :dayOfYear = dayOfYear(:date2);
*inlr = *on ;
If endProgram = 'Y' ;
CEETREC(*omit: 0) ; // exit Program
EndIf ;
RETURN ;
END-PROC;
CEE Date APIs
The CEE APIs offer tremendous flexibility. The format word allows the API to return a string that could be a three-letter day, the number of the day of the week, or the date, or even the text of the month, day of the week, and year.
Ctl-Opt Option( *NoDebugIO : *SrcStmt ) DftActGrp( *No )
ActGrp( 'DATE1' ) PgmInfo( *PCML : *Module )
Main(Main) BNDDIR('QC2LE':'SC0000_BD') ;
Dcl-Pr CEETREC extproc('CEETREC');
rc Int(10) const options(*omit) ;
user_rc Int(10) const options(*omit) ;
End-Pr;
Dcl-PR CEEDAYS ExtProc('CEEDAYS') OpDesc ;
DateString char(32) Const ;
FormatString char(32) Const ;
LilianDate int(10) ;
Error char(12) Options(*Omit) ;
End-Pr;
Dcl-PR CEEDATE ExtProc('CEEDATE') OpDesc ;
LilianDate int(10) Const ;
FormatString char(32) Const ;
DateString char(32) ;
Error char(12) Options(*Omit) ;
End-Pr;
Dcl-PR CEEDYWK ExtProc('CEEDYWK') OpDesc ;
LilianDate int(10) Const ;
dayOfWeek int(10) Const ;
Error char(12) Options(*Omit) ;
End-Pr;
Dcl-DS *n ;
DiffDate zoned(8:0) ;
DiffYears zoned(4:0) overlay(DiffDate) ;
DiffMonths zoned(2:0) overlay(DiffDate: *Next) ;
DiffDays zoned(2:0) overlay(DiffDate: *Next) ;
END-DS;
Dcl-DS CeeFB ;
MsgSev uns(5) ; // 2-byte severity code
MsgNo uns(5) ; // 2-byte message code
Bits char(1) ;
** Case - 2-bits defining format of condition
** Severity - 3-bits defining condition severity
** Control - 3-bits describing control variables
Facilyty_id char(3) ;
I_S_Info uns(10) ; // 0=no message issued
End-DS ;
Dcl-S Today date inz(*sys) ;
Dcl-S sWorkDate char(8) ;
Dcl-S sDateInWords char(32) ;
Dcl-S nLil int(10) ;
Dcl-S sFormat char(32) ;
Dcl-S ceeWeekDay int(10) ;
Dcl-Proc Main ;
Dcl-PI *n extPgm('DATECEE') ;
endProgram char(1) const ;
END-PI ;
Exec SQL
set option
Commit = *None,
Naming = *Sys,
DECRESULT = (63, 63, 0),
datfmt = *ISO ;
sFormat = 'Wwwwwwwwwz, Mmmmmmmmmz ZD, YYYY' ;
sWorkDate = %char(Today: *iso0) ;
Callp(e) CEEDAYS (sWorkDate: 'YYYYMMDD': nLil : *Omit) ;
Callp(e) CEEDATE (nLil: sFormat: sDateInWords: *Omit) ;
Callp(e) CEEDYWK (nLil: ceeWeekDay : *Omit) ;
*inlr = *on ;
If endProgram = 'Y' ;
CEETREC(*omit: 0) ; // exit Program
EndIf ;
RETURN ;
END-PROC;
Lilian Date Picture string
| Picture String | Character String |
|---|---|
|
YY
YYMM YY-MM YYMMDD YYYYMMDD YYYY-MM-DD YYYY-ZM-ZD |
88
8805 88-05 880516 19880516 1988-05-16 1988-5-16 Showa 63.05.16 (in a DBCS string) MinKow 77.05.16 (in a DBCS string) |
| MM
MMDD MM/DD MMDDYY MM/DD/YYYY ZM/DD/YYYY |
05
0517 05/17 051788 05/17/1988 5/17/1988 |
| DD
DDMM DDMMYY DD.MM.YY DD.MM.YYYY DD Mmm YYYY |
18
1805 180588 18.05.88 18.05.1988 18 May 1988 |
| DDD
YYDDD YY.DDD YYYY.DDD |
140
88140 88.140 1988.140 |
|
YY/MM/DD HH:MI:SS.99
YYYY/ZM/ZD ZH:MI AP |
88/05/20 00:00:00.00
88/5/20 0:00 AM |
| WWW., MMM DD, YYYY
Www., Mmm DD, YYYY Wwwwwwwwww, Mmmmmmmmmm DD, YYYY Wwwwwwwwwz, Mmmmmmmmmz DD, YYYY |
SAT., MAY 21, 1988
Sat., May 21, 1988 Saturday , May 21, 1988 Saturday, May 21, 1988 |