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 |