## system date

1955 pts.
Tags:
AS/400
Hi, How to write a CL program. Provided--SAT/SUN/25th Dec /1st Jan are holidays. Then how to compare current system date with above holidays plus either of these days *TUE/*WED/*THU. Thanks

Software/Hardware used:
AS/400
Related Questions

Thanks. We'll let you know when a new response is added.

## Discuss This Question: 49 Replies

Thanks. We'll let you know when a new response is added.
• Please provide more detail. Are you looking to determine if the SystemDate is not a 'holiday' nor a *TUE/*WED/*THU? That is, it's both (a *MON or a *FRI) and not (25th Dec nor 1st Jan).

It's not clear what the exact requirements are.

Tom

report
• Just for more clarification.

Business days:-MON-FRI except 25th Dec and 1st Jan.

Holidays:- SAT,SUN,25th Dec,1st Jan

Objective:- To compare current system date with next  business day if it'sTUE,WED,THU and 1stJan or 25th Dec.

Thanks

report
• ...if it's TUE,WED,THU...

What is "it"? Current system date? Or "next business day"?

Tom

report

report
• Objective:- To compare current system date with next Business day and Next Business day can be TUE,WED,THU and 25th Dec or 1st Jan.

report
• I think the wording seems wrong. It seems that you don't want to "compare" the two dates. Instead, I would think that you want to determine what the next business day is.

In order to compare two dates, you need to know what the dates are. The current system date is easy to get, but from where will you retrieve the next business day? And what would be the result of a comparison? The only possible result would be that current date would be 'less than' or 'earlier than' the next business day.

That isn't making sense, so I have to think that you want to find the next business day.

But a complication is that the dates that you find must always be *TUE/*WED/*THU, and they can't be 25th Dec nor 1st Jan.

To me, it seems that you need to add one day to current system date. Then you have to test the result to see if it's *TUE/*WED/*THU. If it isn't, then add one more day and keep testing until *TUE/*WED/*THU is reached.

When you find the next day that is *TUE/*WED/*THU, you need to test for 25th Dec or 1st Jan. If that date is one of those, you need to add one day again and loop back to the start of the tests. But if it's not 25th Dec nor 1st Jan, then you're done.

At the end, you have found the next business day that is *TUE/*WED/*THU and is also not 25th Dec nor 1st Jan.

The logic and programming wouldn't be terribly difficult, but it might not be very efficient. The best way to do it might depend on how often the process should run. If it's only run once in a process, the basic logic above could be directly written in the process. But if it's going to run thousands of times in a job, then some changes should be made.

So, do you want to "compare" or do you want to "find" the next business day?

Tom

report
• Given the differences that occur it would be better to have a file of dates.- dayname - Holiday, Weekend, etc.

We found that this was especially true when we started supporting factories and offices with different schedules, locations in different states and different countries.

Each unit had a seperate calender.  If a factory was going to run Saturdays for a month it's calander was changed to reflect that plan.  Units within a single factory might require seperate calendars.

If Chrismas fell on the weekend, another day might be given for the holiday.

If a storm takes out a plant, it might be off-line for a week.

report
• if next business day from current system date  falls on either tue,wed,thu and either of 25th dec or 1st jan.then need to run some queries.

so how to increase current system date by 1 or 2 and then compare next business day and find out whether it's tue/wed/thu and either of 25th dec or 1st jan.

all this needs to be done through cl program.

so both is required comparision as well to find out next business day then only next steps can be taken.

Thanks

report
• .But a complication is that the dates that you find must always be *TUE/*WED/*THU, and they can't be 25th Dec nor 1st Jan

---> next business  dates must always be *TUE/*WED/*THU, and  25th Dec or 1st Jan.

report
• next business  dates must always be *TUE/*WED/*THU, and  25th Dec or 1st Jan.

That means that the queries will not run every year. They would run this year and next year, but not in 2015, 2016 or 2017. Those dates only fall on those days of the week in three out of every seven years.

Tom

report
• For simple example:-

let's say lets say current system date is x and next business day is y.

then programaticaally need to identify if y falls either TUE/WED/THU/25DEC/1st Jan.

once day of y and also date(25thdec/1st Jan) is known then current objective should be completed.

Thanks

report
• Queries can only run on the current date. It will always be the "current date" when a query runs. It will never be the "next business day".

So now what I understand is that you want to run a query if current day is *MON/*TUE/*WED and the current date is 24th Dec or 31st Dec. That would automatically mean that the next day would be *TUE/*WED/*THU and would also be 25th Dec or 1st Jan.

Tom

report
• ya,that's right query will run from MON-FRI (not on SAT/SUN/25th DEC/1st Jan)

But once it runs it would check whether next business day is *TUE/*WED/*THU /25th Dec/1st Jan.

report
• So how to check programmatically seeing current system date and compare whether next business day falls on *TUE/*WED/*THU/25th Dec/1st Jan

Thanks

report
• overall to find out next busness is 25th Dec or 1st Jan seems to be difficult.
report
• not sure may require calender experts....
report
• I've been using this service program for some time:

```H nomain

D Dayofweek       Pr             1p 0
D  inputdate                      d

D Dayname         Pr             9
D  inputdate                      d

* ====================================================================================================================
* Dayofweek  - Calculate day of the week from input date
* ====================================================================================================================
P Dayofweek       B                   Export

D Dayofweek       Pi             1p 0
D  workdate                       d

D Anysunday       S               d   inz(d'1582-10-17')
D Worknum         S              7  0
D Workday         S              1p 0

C     workdate      Subdur    anysunday     worknum:*d
C     worknum       Div       7             worknum
C                   Mvr                     workday
C                   If        workday <= *zero
C                   Return    workday + 7

C                   Else
C                   Return    workday
C                   EndIf

P Dayofweek       E

* ====================================================================================================================
* Dayname    - Return name of week day from given date
* ====================================================================================================================
P Dayname         B                   Export

D Dayname         Pi             9
D  workdate                       d

D Namedata        Ds
D  data                         63    inz('Monday   Tuesday  WednesdayThur+
D                                     sday Friday   Saturday Sunday')
D   name                         9    overlay(data:1) dim(7)

C                   Return    name(dayofweek(workdate))

P Dayname         E   ```
report
• overall to find out next busness is 25th Dec or 1st Jan seems to be difficult.

First, the "next business day" will never be 25th Dec or 1st Jan unless your definitions are wrong. At the beginning, you said that 25th Dec or 1st Jan were "holidays", not "business days".

You said:

• SAT/SUN/25th Dec /1st Jan are holidays.

That's an example of giving clear requirements to avoid confusion.

Regardless, all you need to do is test if current date is 24th Dec or 31st Dec. If it is, then simply test if current day is *MON/*TUE/*WED.

If both of those tests are true, then you know that next business day must be *TUE/*WED/*THU and its date will be either 25th Dec or 1st Jan.

If you think that won't work, please show an example date where it will fail.

Tom

report
• What if suppose if today 22nd Dec and it's friday then on 23(sat),24th(sun) and 25thDec(Mon
)

In his case after friday next business day is actually Monday(25th Dec) but 25th Dec being a holiday for example here in this example fell on monday similarly it may fall on friday or any day of week.

Then?

report

Thanks

report
• In his case after friday next business day is actually Monday(25th Dec) but 25th Dec being a holiday for example here in this example fell on monday similarly it may fall on friday or any day of week.

Then?

Then what? It doesn't fit your stated requirements, so it would be ignored. That's what you said should happen, so it's correct.

...next  business day if it'sTUE,WED,THU and 1stJan or 25th Dec....

But apparently that is not what you actually need. Now it seems that it should be:

...next  business day if it's (TUE,WED,THU OR ((1stJan or 25th Dec) and Mon,Fri)....

That makes a big difference. I'll need to think through it again because it changes what is being detected.

Tom

report
• Wouldn't it be simpler with a calendar file?

There will be likely be more rules and exceptions.

report
• With the latest probable change to requirements, a 'calendar' might become the simplest solution. But the actual requirements still might be incomplete or need further correcting. -- Tom
report
• Requirement is straight forward :-

Business days are Monday to Friday.

Holidays are Saturday,Sunday, 25th Dec and 1st Jan.(And 25th Dec and 1st Jan may fall on any day of the week but they will always be holidays)

Scheduled job will run from Monday to Friday except 25th Dec and 1st Jan. and will check and compare from current system date whether next business falls on *TUE,*WED,*THU and 25th Dec or 1st Jan.This needs to be checked through CL program.

Also what is this 'calendar' file and how can the current system date be increased by 1 or 2 or 3 days using CL program.

Thanks

report
• ...whether next business falls on *TUE,*WED,*THU and 25th Dec or 1st Jan.

But that contradicts your statement about when it's *MON and 25th Dec or 1st Jan. If it's *MON and 25th Dec, then it's definitely not "*TUE,*WED,*THU and 25th Dec". It can't be both ways.

Tom

report
• if monday falls on 25th Dec/1St Jan , then no issues since it's being 25th Dec/1st Jan  this will be a holiday.

So main objective is to check if the next business day is *tue/*wed/*thu/25th Dec/1st Jan.

Thanks

report
• it's simple:-

rtvsysval qdate,qdayof week.

check day of week if mon/tue/wed

and qdate+1 or qdate+2 =25th dec or 1st jan

report
• key concept:- xmas/new year will fall mon-fri or sat/sun

if suppose xmas/new yr. falls on monday then on friday pgm will check if current system date +3 dys=25thdec/1st jan.

or in between mon-thu -->xmas/new yr. falls then pgm will check current system date+1 day in advance and check whether next business day is xmas/new yr.

and for sat/sun --even if xmas/new yr. falls then no no need to check since already being sat/sun are holidays(non business days)

Thanks

report
• Hi,

I have written following CL program:-

FMT **  ...+... 1 ...+... 2 ...+... 3 ...+... 4 ...+... 5 ...+... 6 ...+... 7
*************** Beginning of data *************************************
0000.01 PGM
0001.03              DCL        VAR(&DATE) TYPE(*CHAR) LEN(6)
0001.04              DCL        VAR(&DATE1) TYPE(*CHAR) LEN(10)
0001.05              DCL        VAR(&DAY) TYPE(*CHAR) LEN(4)
0002.00              RTVSYSVAL  SYSVAL(QDATE) RTNVAR(&DATE)
0002.01              RTVSYSVAL  SYSVAL(QDAYOFWEEK) RTNVAR(&DAY)
0002.02              CVTDAT     DATE(&DATE) TOVAR(&DATE1) TOFMT(*YYMD) TOSEP(-)
0003.00              CALL       PGM(LIBA /RP1) PARM(&DATE1)
0003.01              IF         COND(&DAY *EQ *MON *OR &DAY *EQ *TUE *OR +
0003.02                           &DAY *EQ *WED)
0004.00 ENDPGM
****************** End of data ****************************************

called RPGLE RP1 for date checking(whether next business day is 25th Dec/1st Jan)

RP1:-

FMT D  DName+++++++++++ETDsFrom+++To/L+++IDc.Keywords+++++++++++++++++++++++++
*************** Beginning of data *************************************
000.01 ddate1            s               D
000.02 ddate2            s               d
000.03 ddate3            s               d
002.00 C     *ENTRY        PLIST
003.00 C                   PARM                    DATE1
004.00 C     date1         ADDDUR    01:*D         DATE1
004.01 C     date1         ADDDUR    03:*D         DATE2
004.02 C                   extrct    date1:*M      month12           2 0
004.03 C                   extrct    date1:*D      DAY25             2 0
004.04 C                   extrct    date2:*M      month1            2 0
004.05 C                   extrct    date2:*D      DAY1              2 0
004.06 C                   IF        MONTH12=12 AND DAY25=25 OR MONTH12=01 and
004.07 C                             +day25=01 or Month1=12 and day1=25 or
004.08 C                             month1=01 and day1=01
004.09 c                   return
004.10 C                   ENDIF

Then in above RP1 program,after checking the IF condition( comparing current system date by adding 1 or 3 days ) if next business day is found to be either 25th Dec or 1 st jan then in Above CL program how to proceed further or how to make next

steps so that conditions next business day is either *tue/*wed/*thu/25th dec/1st jan

could be satisfied.

Thanks!

report
• ..Also not sure whether CL it self provide any facility to increase the current system date by 1 or 3 itself or not ,that's why called the above RP1 so that because of some useful

opcodes like ADDDUR,EXTRCT in RPGLE can help in achieving the required target.

Thanks

report

Thanks

report

Thanks

report
• You could in CL convert the system date to Julian, Add a day, Convert it back.

If the next day is NOT a saturday, Sunday or holiday it should be your next BUSINESS day. Jobs should run.

If the next day is a Saturday, Sunday or Holiday loop through, and add 1 more day and try again until the date equals the next business day.

Consider adding the day of week process to your holiday process RPGLE.

Also add a paramerter to pass back to the CL the result of your test.

How will the CL know the result of your test?

report
• Hi,

But how to add that parameter in RPGLE and pass back to cl:-

i tried below but looks faling somewhere like recurrersive call And still it's not working as expected.:

CLLE-->RPGLE--->CLLE--->RPGLE..-->.CLLE Never ending process

RP1--just name changed to CL91RPGLE here:-

PGM        PARM(&HDAY)
DCL        VAR(&DATE) TYPE(*CHAR) LEN(6)
DCL        VAR(&DATE1) TYPE(*CHAR) LEN(10)
DCL        VAR(&DAY) TYPE(*CHAR) LEN(4)
DCL        VAR(&HDAY) TYPE(*CHAR) LEN(7)
DCL        VAR(&FLAG1) TYPE(*DEC) LEN(1)
RTVSYSVAL  SYSVAL(QDATE) RTNVAR(&DATE)
RTVSYSVAL  SYSVAL(QDAYOFWEEK) RTNVAR(&DAY)
CVTDAT     DATE(&DATE) TOVAR(&DATE1) TOFMT(*YYMD) TOSEP(-)
CALL       PGM(LIBA/CL91RPGLE) PARM(&DATE1)
IF         COND(&DAY *EQ *MON *OR &DAY *EQ *TUE *OR +
&DAY *EQ *WED *OR &HDAY *EQ 'HOLIDAY') +
THEN(CHGVAR VAR(&FLAG1) VALUE(1))
ELSE       CMD(CHGVAR VAR(&FLAG1) VALUE(0))
endpgm

CL91RPGLE Code:-

DDATE1            S               D
DDATE2            S               D
DDATE3            S               D
DHDAY             S              7    INZ('       ')
C     *ENTRY        PLIST
C                   PARM                    DATE1
C                   EXTRCT    DATE1:*M      MONTH12           2 0
C                   EXTRCT    DATE1:*D      DAY25             2 0
C                   EXTRCT    DATE2:*M      MONTH1            2 0
C                   EXTRCT    DATE2:*D      DAY1              2 0
C                   IF        MONTH12=11 AND DAY25=20 OR MONTH12=01 anD
C                             day25=01 or Month1=12 and day1=25 or
C                                    month1=01 and day1=01
C                   DO

C                                    month1=01 and day1=01
C                   DO
C                   EVAL      HDAY='HOLIDAY'
C                   CALL      'CL90'
C                   PARM                    HDAY
C                   ENDDO
C                   ENDIF
C                   RETURN

..slightly changed if condition let's assume 20th Nov is 25th dec(XMAS) for time being for testing above programs.

but even after passing parameter 1) seems not geting passed properly 2)please advise if the above logic is fine to obtain desired target.

Thanks.

report
• There are multiple contradictions in the requirements that have been given in different comments. The contradictions mean that it is impossible to make this work. The contradictions must be resolved.

For example, the comment dated Nov 15, 2013   2:49 AM GMT appears to contradict the comment dated Nov 16, 2013   7:11 AM GMT . I can't see any way that both of those can be true. The Nov 15 comment appears to be a response to the comment that immediately precedes it.

However, maybe the way to get to an answer is to look at code. As code is reviewed, it can be changed to make corrections as needed. This code seems to be a close approximation to a likely interpretation of the requirements:

```pgm

dcl   &QDATE       *char     6
dcl   &QDOW        *char     4

dcl   &QMMDD       *char     4

dcl   &RunQry      *lgl

rtvsysval   QDATE      rtnvar( &QDATE   )
rtvsysval   QDAYOFWEEK rtnvar( &QDOW    )

chgvar      &QMMDD             %sst( &QDATE 1 4 )

/* +
Note 1: Tests today for *MON/*TUE/*WED...                              +
Note 2: Tests today for *THU to see if tomorrow is 25th Dec or 1st Jan +
Note 3: Tests today for *FRI to see if Monday is 25th Dec or 1st Jan   +
*/
select

/* Note 1 */
when ( &QDOW *eq '*MON' *or &QDOW *eq '*TUE' *or &QDOW *eq '*WED' )  +
chgvar  &RunQry  '1'

/* Note 2 */
when ( &QDOW *eq '*THU' +
*and ( &QMMDD *eq '1224' *or &QMMDD *eq '1231' ) )  +
chgvar  &RunQry  '1'

/* Note 3 */
when ( &QDOW *eq '*FRI' +
*and ( &QMMDD *eq '1222' *or &QMMDD *eq '1229' ) )  +
chgvar  &RunQry  '1'

otherwise  +
chgvar  &RunQry  '0'

endselect

if ( &RunQry *eq '1' )  +
runqry *n MyQry

return

endpgm```

The code assumes that the jobs DATFMT() is *MDY. If the date format is *YMD or *DMY, then the %SST() that extracts the month-day value needs to be altered. Also, if the job date format is *DMY, then the month-day constants in the WHEN statements need to be altered.

Other than those possible changes, the changes that might be needed would be to add or remove WHEN statements to or from the SELECT group. Also, the RUNQRY statement at the end needs to be replaced with whatever query will actually be run.

Tom

report
• If we had a file with these three fields .. perhaps a few more depending on your logic.

It would take a few minutes to write a program to load 20 years of data.

Date                   DayOfWeek    Process

11/19/2013         *TUE              YES

11/20/2013         *WED             YES

11/21/2013         *THU              YES

11/22/2013          *FRI               NO

Now create a simple RPG program to chain into the file on date and return the date, day-of-week and process.  I got lost in your logic but if you need to "look forward" you would just read additional rows until you find the value you want.  You can change the data to deal with different rules.

report
• There are multiple contradictions in the requirements that have been given in different comments. The contradictions mean that it is impossible to make this work. The contradictions must be resolved.....

The above suggested code will not include the condition if next business day is *TUE,*WED,*THU and EITHER OF 25th Dec or 1 st Jan.(means next working day from today's date(current system date +1)

Advised code will check 25th Dec/1st jan only on either friday or monday.

Please go through below written code hopefully which may clarify exact requirement:-

*********************************************************8
PGM        PARM(&HDAY1)
DCL        VAR(&DATE) TYPE(*CHAR) LEN(6)
DCL        VAR(&DATE1) TYPE(*CHAR) LEN(10)
DCL        VAR(&DAY) TYPE(*CHAR) LEN(4)
DCL        VAR(&HDAY1) TYPE(*CHAR) LEN(7)
DCL        VAR(&HDAY3) TYPE(*CHAR) LEN(7)
DCL        VAR(&FLAG1) TYPE(*DEC) STG(*AUTO) LEN(1) +
VALUE(1)
RTVSYSVAL  SYSVAL(QDATE) RTNVAR(&DATE)
RTVSYSVAL  SYSVAL(QDAYOFWEEK) RTNVAR(&DAY)
CVTDAT     DATE(&DATE) TOVAR(&DATE1) TOFMT(*YYMD) TOSEP(-)
IF         COND(&HDAY1 *EQ 'HOLIDAY') THEN(GOTO +
CMDLBL(R1))
CALL       PGM(LIBA/HDAY2) PARM(&DATE1)
R1:         CHGVAR     VAR(&HDAY3) VALUE(&HDAY1)
IF         COND((&DAY *EQ *MON *OR &DAY *EQ *TUE *OR +

&DAY *EQ *WED) *AND (&HDAY3 *EQ HOLIDAY)) +
THEN(DO)
RUNQRY     QRY(LIBA/Q2.1)
RUNQRY     QRY(LIBA/Q2.2)
ENDDO
IF         COND((&DAY *EQ *THU *OR &DAY *EQ *FRI) *AND +
(&HDAY3 *EQ HOLIDAY)) THEN(DO)
RUNQRY     QRY(LIBA/Q4.1)
RUNQRY     QRY(LIBA/Q4.2)
RUNQRY     QRY(LIBA/Q4.3)
RUNQRY     QRY(LIBA/Q4.4)
ENDDO
IF         COND((&DAY *EQ *MON *OR &DAY *EQ *TUE *OR +
&DAY *EQ *WED *OR &DAY *EQ *THU) *AND +
(&HDAY3 *NE HOLIDAY)) THEN(DO)
RUNQRY     QRY(LIBA/Q1.1)
ENDDO

ENDDO
IF         COND((&DAY *EQ *FRI) *AND (&HDAY3 *NE +
HOLIDAY)) THEN(DO)
RUNQRY     QRY(LIBA/Q3.1)
RUNQRY     QRY(LIBAI/Q3.2)
RUNQRY     QRY(LIBAI/Q3.3)
ENDDO
ENDPGM

***********************************

Code of HDAY2:-

.00 DDATE1            S               D
.00 DDATE2            S               D
.00 DHDAY1            S              7    INZ('       ')
.00 C     *ENTRY        PLIST
.00 C                   PARM                    DATE1
.00 C     date1         ADDDUR    01:*D         DATE1
.00 C     date1         ADDDUR    03:*D         DATE2
.00 C                   extrct    date1:*M      month12           2 0
.00 C                   extrct    date1:*D      DAY25             2 0
.00 C                   extrct    date2:*M      month1            2 0
.00 C                   extrct    date2:*D      DAY1              2 0
.00 C                   IF        MONTH12=11 AND DAY25=22 OR MONTH12=01 and
.00 C                             +day25=01 or Month1=11 and day1=18 or
.00 C                             month1=01 and day1=01
.00 c                   eval      hday1  ='HOLIDAY'
.01 C                   CALL      'CLWRK5'

c                   PARM                    HDAY1
C                   ENDIF
C                   RETURN

And advise if above can still cause some one to get lost in above program. However a full excercise has been done to make flow clear.

Thanks

report
• ..sorry small correction in RPGLE (HDAY2)..IN IF condition(which determines or heart of

Holiday logic :- 25th Dec/1st Jan may fall1) MON-FRI  2) SAT-SUN.(if it falls on sat/sun then no problem-since job will run from Monday to friday only and in between it will check every thing)

if it falls on 1) MON- FRI then either from current system date + 1 will be 25th Dec/1st Jan

OR

Current system date +3 =25th Dec/1st Jan(only for considering Monday being 25th Dec/1st Jan and deliberately leaving SAT/SUN-Since 25th Dec//1st Jan falls on SAT/SUN-Then no issues. )

So correction in IF condition is:-

IF        MONTH12=12AND DAY25=25 OR MONTH12=01 and
.00 C                             +day25=01 or Month1=12 and day1=25 or
.00 C                             month1=01 and day1=01

Thanks

report
• Now the requirements have apparently changed again. It looks like different conditions cause different queries to run. Under different conditions, the requirements are to run:

```             RUNQRY     QRY(LIBA/Q2.1)
RUNQRY     QRY(LIBA/Q2.2)
...or:
RUNQRY     QRY(LIBA/Q4.1)
RUNQRY     QRY(LIBA/Q4.2)
RUNQRY     QRY(LIBA/Q4.3)
RUNQRY     QRY(LIBA/Q4.4)
...or:
RUNQRY     QRY(LIBA/Q1.1)
...or:
RUNQRY     QRY(LIBA/Q3.1)
RUNQRY     QRY(LIBAI/Q3.2)
RUNQRY     QRY(LIBAI/Q3.3)```

Again it's not clear what is needed. Does the code that you just posted work or not? If it doesn't work, what goes wrong? When does it fail?

Here's a variation of the code I posted in my previous comment:

```pgm

dcl   &QDATE       *char     6
dcl   &QDOW        *char     4

dcl   &QMMDD       *char     4

dcl   &RunQry      *lgl

dcl   &RunQryTyp   *char     1

rtvsysval   QDATE      rtnvar( &QDATE   )
rtvsysval   QDAYOFWEEK rtnvar( &QDOW    )

/* -------------------------------------------- */
/* Fake QDATE... */

chgvar      &QDATE                   '112513'

/* Fake QDATE... */

chgvar      &QDOW                    '*MON'

/* -------------------------------------------- */
/* Run with fake values... */
chgvar      &QMMDD             %sst( &QDATE 1 4 )

/* +
Note 1: Tests today for *MON/*TUE/*WED...                              +
Note 2: Tests today for *THU to see if tomorrow is 25th Dec or 1st Jan +
Note 3: Tests today for *FRI to see if Monday is 25th Dec or 1st Jan   +
*/
select

/* Note 1 */
when ( &QDOW *eq '*MON' *or &QDOW *eq '*TUE' *or &QDOW *eq '*WED' )  do
chgvar  &RunQryTyp  '1'
chgvar  &RunQry     '1'
enddo

/* Note 2 */
when ( &QDOW *eq '*THU' +
*and ( &QMMDD *eq '1224' *or &QMMDD *eq '1231' ) )  do
chgvar  &RunQryTyp  '2'
chgvar  &RunQry     '1'
enddo

/* Note 3 */
when ( &QDOW *eq '*FRI' +
*and ( &QMMDD *eq '1222' *or &QMMDD *eq '1229' ) )  do
chgvar  &RunQryTyp  '3'
chgvar  &RunQry     '1'
enddo

otherwise  do
chgvar  &RunQryTyp  '4'
chgvar  &RunQry     '0'
enddo

endselect

dmpclpgm

return

endpgm```

It has the same logic, but it's been modified to test if the logic is correct. It doesn't use the real QDATE and QDAYOFWEEK system values. Instead it shows one way to put any values you want to test into those values. If you change "fake" values to be different dates or different days of week, the result in &RunQryTyp will change. The DMPCLPGM statement at the end will tell you if the logic assigned the correct value to &RunQryTyp.

The "fake" values are set in CHGVAR statements from literal constants. The values could instead be supplied as parms. By changing those values, any combination can be tested. Whenever a combination gives incorrect results, the WHEN clauses can be changed to whatever is needed. If a new WHEN clause needs to detect a new condition, it can easily be inserted wherever it should be.

Once the final logic works, the code that sets the "fake" values can be removed, and any needed RUNQRY statements can be inserted into their appropriate WHEN clauses.

Tom

report
• Are these the only 2 holidays you have concern about? What happens next year?  I read in an earlier post suggesting a "calendar file".  We use those a lot. As part of our year end process we add the new dates and can then check them by chaining to this file in RPGLE or use a RCVF in a CLLE program.  From all the posts above there seems to be no definite specifications as to what is needed or this would have been solved days ago.

report
• From all the posts above there seems to be no definite specifications as to what is needed or this would have been solved days ago.

It seems like every time a possible solution is suggested, a new requirement is added that invalidates the solution. At a couple points, some requirements seem to contradict others.

I can only think to provide code that shows one way to do some testing. With the alternative code samples also provided, there doesn't seem much else to do.

Tom

report
• ..Sorry if above has failed to clarify exact requirement. Basically exact scenario is like following:-

If next business day is (Tue, Wed, Thu) and (Jan1st  or Dec 25th )

Run Q2.1 and Q2.2

If next business day is (Mon or Fri) and (Jan1st  or Dec 25th )

Run Q4.1, Q4.2, Q4.3 and Q4.4

If next business day is (Tue, Wed, Thu or Fri) and NOT (Jan1st  or Dec 25th )

Run Q1.1

If next business day is  (Mon) and NOT (Jan1st  or Dec 25th )

Run Q3.1,Q3.2 and Q3.3

Basically

we need to run 1 query on (T) if  (T+1) is NOT a holiday, Saturday or Sunday

run 2 queries on (T) if  (T+1)  is a holiday

run 3 queries on (T) if  (T+1)  & (T+2) are Saturday and Sundays

run 4 queries on (T) if (T+1) (T+2) are Saturday and Sundays and (T+3) is a holiday

**********************

So considering above requirement please find below Modified program with CL and RPG:-

CL:  CLnew:-

PGM        PARM(&HDAY1)
DCL        VAR(&DATE) TYPE(*CHAR) LEN(6)
DCL        VAR(&DATE1) TYPE(*CHAR) LEN(10)
DCL        VAR(&DAY) TYPE(*CHAR) LEN(4)
DCL        VAR(&HDAY1) TYPE(*CHAR) LEN(7)
DCL        VAR(&HDAY3) TYPE(*CHAR) LEN(7)
DCL        VAR(&FLAG1) TYPE(*DEC) STG(*AUTO) LEN(1) +
VALUE(1)
MONMSG     MSGID(CPF0000 RPG0000 MCH0000) EXEC(GOTO +
CMDLBL(ERROR))
RTVSYSVAL  SYSVAL(QDATE) RTNVAR(&DATE)
RTVSYSVAL  SYSVAL(QDAYOFWEEK) RTNVAR(&DAY)
CVTDAT     DATE(&DATE) TOVAR(&DATE1) TOFMT(*YYMD) TOSEP(-)
IF         COND(&HDAY1 *EQ 'HOLIDAY') THEN(GOTO +
CMDLBL(R1))
CALL       PGM(LIBAI/NEWRPG) PARM(&DATE1)

CALL       PGM(LIBA/NEWRPG) PARM(&DATE1)
MONMSG     MSGID(CPF0006)
R1:         CHGVAR     VAR(&HDAY3) VALUE(&HDAY1)
IF         COND((&DAY *EQ *MON *OR &DAY *EQ *TUE *OR +
&DAY *EQ *WED) *AND (&HDAY3 *EQ HOLIDAY)) +
THEN(DO)
RUNQRY     QRY(LIBA/Q2.1)
RUNQRY     QRY(LIBA/Q2.2)
ENDDO
IF         COND((&DAY *EQ *THU *OR &DAY *EQ *FRI) *AND +
(&HDAY3 *EQ HOLIDAY)) THEN(DO)
RUNQRY     QRY(LIBA/Q4.1)
RUNQRY     QRY(LIBA/Q4.2)
RUNQRY     QRY(LIBA/Q4.3)
RUNQRY     QRY(LIBA/Q4.4)
ENDDO
IF         COND((&DAY *EQ *MON *OR &DAY *EQ *TUE *OR +

&DAY *EQ *WED *OR &DAY *EQ *THU) *AND +
(&HDAY3 *NE HOLIDAY)) THEN(DO)
RUNQRY     QRY(LIBA/Q1.1)
ENDDO
IF         COND((&DAY *EQ *FRI) *AND (&HDAY3 *NE +
HOLIDAY)) THEN(DO)
RUNQRY     QRY(LIBA/Q3.1)
RUNQRY     QRY(LIBA/Q3.2)
RUNQRY     QRY(LIBA/Q3.3)
ENDDO
GOTO       CMDLBL(END)
ERROR:      SNDEMLMSG  TO(name1@.... SUBJECT('Some +
issue in Query')
END:        ENDPGM

**********************************************************

RPG:-

DDATE1            S               D
DDATE2            S               D
DDATE3            S               D
DHDAY1            S              7    INZ('       ')
C     *ENTRY        PLIST
C                   PARM                    DATE1
C                   extrct    date2:*M      month12           2 0
C                   extrct    date2:*D      DAY25             2 0
C                   extrct    date3:*M      month1            2 0
C                   extrct    date3:*D      DAY1              2 0
C                   IF        MONTH12=12 AND DAY25=25 OR MONTH12=01 and
C                             +day25=01 or Month1=12 and day1=25 or
C                             month1=01 and day1=01
c                   eval      hday1  ='HOLIDAY'
C                   CALL      'NEWCL'
c                   PARM                    HDAY1
C                   ENDIF
C                   RETURN

Main logic:- 25Th Jan/1st Jan may fall either MON-FRI or SAT/SUN.

1) IF 25th Dec/1st Jan Falls on SAT/SUN then no issues.

2) IF it falls on MON-FRI then two cases:--

Case1:- 25th/Dec/1st Jan will be next business day from today's business day(MON-FRI)

Case 2:- 25th Dec/1st  Jan will fall on Monday means after friday suppose next business day is monday and on Monday there is a either 25th Dec/1st Jan.

So considering above logic and requirement, AS/400 experts, please advise whether above written code is fine or may require still some corrections, I have already debugged and tested above and it seems to be working fine. also any other suggestion to handle Error in RPG, however already put some MONMSG in CL to handle error.

Many thanks.

report
• A "truth table" might help to solidify the logic requirement:

```      | Jan 1/Dec 25         | Other
|                      |
*MON  | Q4.1/Q4.2/Q4.3/Q4.4  | Q3.1/Q3.2/Q3.3
|                      |
*TUE  | Q2.1/Q2.2            | Q1.1
|                      |
*WED  | Q2.1/Q2.2            | Q1.1
|                      |
*THU  | Q2.1/Q2.2            | Q1.1
|                      |
*FRI  | Q4.1/Q4.2/Q4.3/Q4.4  | Q1.1```

The "next business day" is given down the first column. The relevant dates are given across the top. The only dates we care about are 25th Dec and 1st Jan. All other dates are simply "Other.

Does the table list the queries in their proper places?

Tom

report
• Yes, truth table is perfect. Please advise the program code for this table or please tell if already shared RPG and CL program also fine to fulfill the requirement.

Thanks a lot.

report
• If the truth table is correct, there is no need for any RPG. The SELECT-group in the previous CL program that I posted can be replaced with:

```/* +
Note 1: Tests today for *MON/*TUE/*WED to see if tomorrow is 25th Dec or 1st Jan +
Note 2: Tests today for *THU to see if tomorrow is 25th Dec or 1st Jan           +
Note 3: Tests today for *FRI to see if Monday is 25th Dec or 1st Jan             +
Note 4: Tests today for *FRI for any other date                                  +
Note 5: Runs today for for any other day & date                                  +
*/
select

/* Note 1 */
when (( &QDOW *eq '*MON' *or &QDOW *eq '*TUE' *or &QDOW *eq '*WED' ) +
*and ( &QMMDD *eq '1224' *or &QMMDD *eq '1231' ) )  do
chgvar  &RunQryTyp  '2'
enddo

/* Note 2 */
when ( &QDOW *eq '*THU' +
and ( &QMMDD *eq '1224' *or &QMMDD *eq '1231' ) )  do
chgvar  &RunQryTyp  '4'
enddo

/* Note 3 */
when ( &QDOW *eq '*FRI' +
*and ( &QMMDD *eq '1222' *or &QMMDD *eq '1229' ) )  do
chgvar  &RunQryTyp  '4'
enddo

/* Note 4 */
when ( &QDOW *eq '*FRI' )  do
chgvar  &RunQryTyp  '3'
enddo

/* Note 5 */
otherwise  do
chgvar  &RunQryTyp  '1'
enddo

endselect```

The four values for &RunQryTyp correspond with the four sets of queries that you want to run. You can put the RUNQRY statements into the WHEN-clause DO-groups, or you can put a simple series of IF-statements after the SELECT-group to run your queries based on the &RunQryTyp value.

Tom

report
• Thanks a ton for this wonderful help and truth table ,this has really made this task very easy and understandable in a brief.

However ,since above advised CL program is itself sufficient to fulfill this complete requirement,can old RPG and CL be also considered as a alternative programming  approach to this requirement as i had debugged and tested all scenarions in that and found that one was also working as per this requirement and seemed to be failing nowhere.

So from my previous CL-RPG approach was some thing wrong in program code,i agree if thing can be  done in a simpler way then why we should make them complex,but just for understanding wanted to know the views of  AS/400 Experts whether previuos RPG and CL posted on 1-12-2013 7.03 AM is also good solution for this task.If not please advise for improvement in the same ,specially from Error handling prpospective in RPG(in CL,Whatever max. MONMSG i could have put already put in code).

Thanks

report
• I can't be sure about your RPG and CL. Who calls the CL and passes in the parm? And then who calls the RPG and passes in its parm? It looks like they call each other, but that doesn't make useful sense. -- Tom
report
• Yes that right they call each other but first CL needs to be called with 7 characters blanks(for HOLIDAY).I have tested it ,initially it was falling in recursive call but ever since i have used level R1 it's not failing and working properly.

Thanks

report
• I don't see why the programs call each other. It would be much easier if the RPG simply returned its value back to the CL. By having he CL called twice, there can be many days when the third or fourth sets of queries can run twice; and it's possible that one of those sets will run when the first or set sets are also run. If the RPG simply returned its 'HOLIDAY' value and didn't issue a new call to the CL, that wouldn't happen.

Also, the RPG doesn't check if the "next business day" is a holiday. Instead, it checks if one or three days in the future is a holiday.

That means it checks if next Saturday is a holiday when the current day is Wednesday and it checks if next Sunday is a holiday when current day is Thursday. Similarly, it checks if Saturday is a holiday when the current day is a Friday.

When Friday is 24th Dec, that means that Saturday will be 25th Dec. The RPG will add one day and find that tomorrow (Saturday) will be a holiday. It will call the CL and run the Friday/holiday queries incorrectly. There are various combinations that will give those incorrect results. As written, there is no way to test for those incorrect results without changing the actual system date for every combination of date and day-of-week. Changing system date is a very bad practice.

At least 25 different combinations of dates and days need to be checked. The current dates that need to be tested are 24th Dec, 22nd Dec, 31st Dec and 29th Dec, plus any other date that will not result in a 'holiday' one or three days in the future, e.g., 1st June. And each of those 'current' dates needs testing for each of the five days-of-week.

Tom