**free/title SQL UDFs to convert numeric to true dates//===============================================================// The DATE_SQL service program contains routines that are// registered as User Defined Functions to SQL and which// convert legacy numeric dates to true dates. This makes doing// date arithmetic in SQL much easier.//// For example, if DSTPT is a 6-digit date in YYMMDD format, in SQL// you can code://// SELECT PNOPT FROM MVPSPRTP// WHERE DATE_YMD(DSTPT) >= CURDATE() - 9O DAYS//// On alder versions of the OS,you may need to cast character dates// to numeric before using.// For example, WHERE DECIMAL(DATE_YMD(DSTPT)) >= ...//// Function included are:// DATE_YMD Accepts numeric dates in YMD format, with// either 6 or 8 digits.// DATE_MDY Accepts numeric dates in MDY format, with// either 6 or 8 digits.// DATE_CYMD Accepts 7 digit numeric dates. If the 1st// digit is 0 then it is in the 1900s and if// it is 1 then it is the 2000s. These are// standard IBM seven byte dates.// ??????? Similar routines could be added to// accept other formats//// For YMD or MDY dates, it handles either 6 or 8 digits.// If the date passed is greater then 999999 then is it// assumed to already have the century.//// Invalid dates return a null value. This means the UDFs will// not crash, but be aware that your results may be skewed if// you have bad data. (Logic could be added to convert// "special" bad dates into some corporately acceptable value,// e.g., 999999 could be converted to 9999-12-31.)//// Originally coded late 1990s, before the Y2K cleanups. Since// tidied up and converted to free form..//// To Create// =========// 1) CRTRPGMOD MODULE(DATE_SQL) SRCFILE(DATE_UDF)// OPTION(*EVENTF) DBGVIEW(*SOURCE)// 2) CRTSRVPGM SRVPGM(DATE_SQL) EXPORT(*ALL)// TEXT('DATE_SQL Service Program')// 3) Run the CREATE_FNSQL statements to register to SQL//===============================================================Ctl-Opt NoMain;//=== Prototypes ================================================Dcl-PR Date_YMD; NumericDate Packed(8:0) const; RealDate Date; Indicators Int(5) dim(1); RetInd Int(5); SQLSTATE Char(5); FuncName Varchar(517); SpecificName Varchar(128); ErrText Varchar(1000);End-PR;Dcl-PR Date_CYMD; NumericDate Packed(8:0) const; RealDate Date; Indicators Int(5) dim(1); RetInd Int(5); SQLSTATE Char(5); FuncName Varchar(517); SpecificName Varchar(128); ErrText Varchar(1000);End-PR;Dcl-PR Date_MDY; NumericDate Packed(8:0) const; RealDate Date; Indicators Int(5) dim(1); RetInd Int(5); SQLSTATE Char(5); FuncName Varchar(517); SpecificName Varchar(128); ErrText Varchar(1000);End-PR;//===============================================================// DATE_YMD// ========// SQL User Defined Function (UDF) converts a 6 or 8 digit// numeric date in YMD format to a true date.//// Returns// =======// If input date is valid, then a true date.// If input date is invalid, returns null with warning 01H99.Dcl-Proc Date_YMD export; Dcl-PI Date_YMD; pDateIn Packed(8:0) const; pDateOut Date; pIndicators Int(5) dim(1); pRetInd Int(5); pSQLSTATE Char(5); pFuncName Varchar(517); pSpecificNam Varchar(128); pErrText Varchar(1000); End-PI; pRetInd = 0; pSQLSTATE = '00000'; monitor; select; // === 8 digit dates, yyyymmdd ================================= when pDateIn > 999999; pDateOut = %date(pDateIn: *ISO); // === 6 digit dates, yymmdd =================================== other; pDateOut = %date(pDateIn: *YMD); endsl; on-error; pRetInd = -1; pDateOut = %date('9999-01-03'); pSQLSTATE = '01H99'; pErrText = %char(pDateIn) + ' is not a (numeric) date'; endmon; return;End-Proc;//===============================================================// DATE_CYMD// =========// SQL User Defined Function (UDF) converts a 7 digit// numeric date in CYMD format to a true date.//// Returns// =======// If input date is valid, then a true date.// If input date is invalid, returns null with warning 01H99.Dcl-Proc Date_CYMD export; Dcl-PI Date_CYMD; pDateIn Packed(8:0) const; pDateOut Date; pIndicators Int(5) dim(1); pRetInd Int(5); pSQLSTATE Char(5); pFuncName Varchar(517); pSpecificNam Varchar(128); pErrText Varchar(1000); End-PI; pRetInd = 0; pSQLSTATE = '00000'; monitor; pDateOut = %date(pDateIn: *CYMD); on-error; pRetInd = -1; pDateOut = %date('9999-01-01'); pSQLSTATE = '01H99'; pErrText = %char(pDateIn) + ' is not a (numeric) date'; endmon; return;End-Proc;//===============================================================// DATE_MDY// ========// SQL User Defined Function (UDF) converts a 6 or 8 digit// numeric date in MDY format to a true date.//// Returns// =======// If input date is valid, then a true date.// If input date is invalid, returns null with warning 01H99.Dcl-Proc Date_MDY export; Dcl-PI Date_MDY; pDateIn Packed(8:0) const; pDateOut Date; pIndicators Int(5) dim(1); pRetInd Int(5); pSQLSTATE Char(5); pFuncName Varchar(517); pSpecificNam Varchar(128); pErrText Varchar(1000); End-PI; pRetInd = 0; pSQLSTATE = '00000'; monitor; select; // === 8 digit dates, mmddyyyy ================================= when pDateIn > 999999; pDateOut = %date(pDateIn: *USA); // === 6 digit dates, mmddyy =================================== other; pDateOut = %date(pDateIn: *MDY); endsl; on-error; pRetInd = -1; pDateOut = %date('9999-01-02'); pSQLSTATE = '01H99'; pErrText = %char(pDateIn) + ' is not a (numeric) date'; endmon; return;End-Proc;