View previous topic :: View next topic |
Author |
Message |
OSCORP Beginner
Joined: 15 Oct 2004 Posts: 29 Topics: 8
|
Posted: Tue Jan 04, 2005 2:03 pm Post subject: Calculate Weekdays in a month |
|
|
Hello All,
Can anyone let me know following:
Using Cobol, or utilities or DB2, can you think of a good way to determine how many Weekday's are in any given month?
For example, January has 21 weekdays (Monday thru Friday). So say I have a parm that says it is January 2005 and I need to find out
1) how many weekday's are in the month
2) what do you think the best way to handle it is?
Regs
OsCorp |
|
Back to top |
|
|
kolusu Site Admin
Joined: 26 Nov 2002 Posts: 12375 Topics: 75 Location: San Jose
|
Posted: Tue Jan 04, 2005 5:13 pm Post subject: |
|
|
Oscorp,
If you can pass the first of the month as the parm-date in CCYY-MM-DD format , then here is a crude way of getting the number of weekdays
Code: |
SELECT DAY(LAST_DAY('2005-01-01')) -
((CASE WHEN A.SAT1 <= LAST_DAY('2005-01-01') THEN 1 ELSE 0 END) +
(CASE WHEN A.SUN1 <= LAST_DAY('2005-01-01') THEN 1 ELSE 0 END) +
(CASE WHEN A.SAT2 <= LAST_DAY('2005-01-01') THEN 1 ELSE 0 END) +
(CASE WHEN A.SUN2 <= LAST_DAY('2005-01-01') THEN 1 ELSE 0 END) +
(CASE WHEN A.SAT3 <= LAST_DAY('2005-01-01') THEN 1 ELSE 0 END) +
(CASE WHEN A.SUN3 <= LAST_DAY('2005-01-01') THEN 1 ELSE 0 END) +
(CASE WHEN A.SAT4 <= LAST_DAY('2005-01-01') THEN 1 ELSE 0 END) +
(CASE WHEN A.SUN4 <= LAST_DAY('2005-01-01') THEN 1 ELSE 0 END) +
(CASE WHEN A.SAT5 <= LAST_DAY('2005-01-01') THEN 1 ELSE 0 END) +
(CASE WHEN A.SUN5 <= LAST_DAY('2005-01-01') THEN 1 ELSE 0 END))
FROM (SELECT DATE(NEXT_DAY(LAST_DAY(DATE('2005-01-01') - 1 MONTH),'SAT'))
SAT1
,DATE(NEXT_DAY(LAST_DAY(DATE('2005-01-01') - 1 MONTH),'SUN'))
SUN1
,DATE(NEXT_DAY(LAST_DAY(DATE('2005-01-01') - 1 MONTH),'SAT') +
7 DAYS ) SAT2
,DATE(NEXT_DAY(LAST_DAY(DATE('2005-01-01') - 1 MONTH),'SUN') +
7 DAYS ) SUN2
,DATE(NEXT_DAY(LAST_DAY(DATE('2005-01-01') - 1 MONTH),'SAT') +
14 DAYS ) SAT3
,DATE(NEXT_DAY(LAST_DAY(DATE('2005-01-01') - 1 MONTH),'SUN') +
14 DAYS ) SUN3
,DATE(NEXT_DAY(LAST_DAY(DATE('2005-01-01') - 1 MONTH),'SAT') +
21 DAYS ) SAT4
,DATE(NEXT_DAY(LAST_DAY(DATE('2005-01-01') - 1 MONTH),'SUN') +
21 DAYS ) SUN4
,DATE(NEXT_DAY(LAST_DAY(DATE('2005-01-01') - 1 MONTH),'SAT') +
28 DAYS ) SAT5
,DATE(NEXT_DAY(LAST_DAY(DATE('2005-01-01') - 1 MONTH),'SUN') +
28 DAYS ) SUN5
FROM SYSIBM.SYSDUMMY1) A
;
|
The Inner select gets all the dates of saturdayt and sundays in a month. The outer select then validates each of the dates and subtracts it from total no: of days in a month.
Hope this helps...
Cheers
kolusu _________________ Kolusu
www.linkedin.com/in/kolusu |
|
Back to top |
|
|
OSCORP Beginner
Joined: 15 Oct 2004 Posts: 29 Topics: 8
|
Posted: Tue Jan 04, 2005 7:21 pm Post subject: |
|
|
Hi Kolusu,
Thanks a lot for the response....
Is there any other way than DB2 (any other IBM utility)??? Currently we dont have DB2 setup at our site....so I cant really test it.
I need to pass the number of weekdays in a shortest possible time from m/f to web....
Regs
OsCorp |
|
Back to top |
|
|
kolusu Site Admin
Joined: 26 Nov 2002 Posts: 12375 Topics: 75 Location: San Jose
|
Posted: Tue Jan 04, 2005 9:34 pm Post subject: |
|
|
Oscorp,
Here is untested code for calculating the weekdays in month when you pass first of the month as the parm-date in CCYYMMDD format.
Code: |
IDENTIFICATION DIVISION.
PROGRAM-ID. WEEKDAYS
AUTHOR. KOLUSU
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-PARM-DATE PIC 9(08).
01 WS-START-DATE REDEFINES WS-PARM-DATE.
05 WS-START-CCYY PIC 9(04).
05 WS-START-MM PIC 9(02).
05 WS-START-DD PIC 9(02).
01 WS-END-DATE.
05 WS-END-CCYY PIC 9(04).
05 WS-END-MM PIC 9(02).
05 WS-END-DD PIC 9(02).
01 WS-MONTH-END-DD PIC X(24) VALUE
'312831303130313130313031'.
01 WS-TBL-MONTH-END REDEFINES WS-MONTH-END-DD.
05 TBL-MONTH-END-DAY PIC 9(02) OCCURS 12 TIMES.
01 WS-DIVIDE-ANSWER PIC S9(08) COMP.
01 WS-INTEGER PIC S9(08) COMP.
01 WS-REMAINDER PIC S9(04) COMP.
01 WS-WEEKDAYS PIC 9(02) VALUE ZERO.
PROCEDURE DIVISION.
PERFORM 1000-INITIALIZATION
PERFORM 2000-GET-MONTH-END-DATE
PERFORM 3000-GET-DAY-OF-WEEK WS-END-DD TIMES
DISPLAY 'THE NO: OF WEEKDAYS : ' WS-WEEKDAYS
GOBACK
.
1000-INITIALIZATION.
ACCEPT WS-PARM-DATE
DISPLAY 'THE PARM-DATE IS : ' WS-PARM-DATE
MOVE WS-PARM-DATE TO WS-END-DATE
.
2000-GET-MONTH-END-DATE.
EVALUATE TRUE
WHEN FUNCTION MOD (WS-END-CCYY 4) NOT ZERO
WHEN FUNCTION MOD (WS-END-CCYY 100) ZERO
AND FUNCTION MOD (WS-END-CCYY 400) NOT ZERO
MOVE '28' TO WS-TBL-MONTH-END (3: 2)
WHEN OTHER
MOVE '29' TO WS-TBL-MONTH-END (3: 2)
END-EVALUATE
MOVE TBL-MONTH-END-DAY(WS-START-MM) TO WS-END-DD
.
3000-GET-DAY-OF-WEEK.
COMPUTE WS-INTEGER = FUNCTION
INTEGER-OF-DATE(WS-PARM-DATE)
DIVIDE WS-INTEGER BY 7 GIVING WS-DIVIDE-ANSWER
REMAINDER WS-REMAINDER
ADD 1 TO WS-REMAINDER
EVALUATE WS-REMAINDER
WHEN 1
WHEN 7
CONTINUE
WHEN OTHER
ADD +1 TO WS-WEEKDAYS
END-EVALUATE
ADD +1 TO WS-START-DD
.
|
Hope this helps...
Cheers
Kolusu _________________ Kolusu
www.linkedin.com/in/kolusu |
|
Back to top |
|
|
kolusu Site Admin
Joined: 26 Nov 2002 Posts: 12375 Topics: 75 Location: San Jose
|
Posted: Tue Jan 04, 2005 9:36 pm Post subject: |
|
|
Quote: |
I need to pass the number of weekdays in a shortest possible time from m/f to web....
|
Oscorp,
Why not do the calculation on the web itself. In Java it is quite easy.
Kolusu _________________ Kolusu
www.linkedin.com/in/kolusu |
|
Back to top |
|
|
OSCORP Beginner
Joined: 15 Oct 2004 Posts: 29 Topics: 8
|
Posted: Tue Jan 04, 2005 11:49 pm Post subject: |
|
|
Hi kolusu,
Thanks for the instant reply...much appreciated.
Even I am coding a cobol program (with the use of DAYOFWEEK function)...dont know whether it will be fast enough...as our system professionals wanted to have a utility which can transfer it in a shortest possible time...
Can't we do this through sort / any other IBM utility??
I agree with you @ handling the date logic on the web....but, I am creating a utility which will do all kinds of date operations which user can think of....here user will just need to set the function code and pass the data, he will get the desired output...this is just a part of it...
Regs
OsCorp |
|
Back to top |
|
|
kolusu Site Admin
Joined: 26 Nov 2002 Posts: 12375 Topics: 75 Location: San Jose
|
Posted: Wed Jan 05, 2005 6:24 am Post subject: |
|
|
Quote: |
Can't we do this through sort / any other IBM utility??
|
Oscorp,
hmm Sort utility does not have the capability of knowing the dayname of a week.
You can run the sql in my first post with DSNTEP2 or DSNTIAUL as a batch job and compare the run times to the cobol pgm.
Quote: |
system professionals wanted to have a utility which can transfer it in a shortest possible time...
|
I haven't tested my cobol pgm , as I just wrote it on the fly, you can do some stress testing on it and post the job statstics here.
Thanks
Kolusu _________________ Kolusu
www.linkedin.com/in/kolusu |
|
Back to top |
|
|
OSCORP Beginner
Joined: 15 Oct 2004 Posts: 29 Topics: 8
|
Posted: Thu Jan 06, 2005 4:23 pm Post subject: |
|
|
Hi kolusu,
I have added one more logic to the program to calculate the weekdays in a date range (between 2 dates)
Program:
Code: |
01 ACCUMULATORS.
05 A-WEEKDAY-COUNT PIC S9(9) COMP-3 VALUE +0.
05 A-WEEKDAY-SKIPPED PIC S9(9) COMP-3 VALUE +0.
01 CONSTANTS.
05 C-MAX-DAYS PIC X(24)
VALUE '312831303130313130313031'.
05 C-TBL-MONTH-END REDEFINES C-MAX-DAYS.
10 TBL-MONTH-END-DAY PIC 9(02) OCCURS 12 TIMES.
01 WORK-AREAS.
05 W-SYSTEM-DATE.
10 W-YEAR PIC 9(04).
10 W-MONTH PIC 9(02).
88 W-VALID-MONTH VALUE 1 THRU 12.
10 W-DAY PIC 9(02).
05 W-RANGE-DATE1.
10 W-YEAR1 PIC 9(04).
10 W-MONTH1 PIC 9(02).
10 W-DAY1 PIC 9(02).
05 W-RANGE-DATE2.
10 W-YEAR2 PIC 9(04).
10 W-MONTH2 PIC 9(02).
10 W-DAY2 PIC 9(02).
05 W-DATE PIC 9(08).
05 WS-MAX-DAY-IN-MONTH PIC 9(02).
05 WS-TOT-PROCESS-DAYS PIC 9(02).
05 WS-DIVIDE-ANSWER PIC S9(08) COMP.
05 WS-REMAINDER PIC S9(04) COMP.
05 WS-INTEGER PIC S9(08) COMP.
LINKAGE SECTION.
01 L-INPUT-PARM.
05 L-PARM-LENGTH PIC S9(04) BINARY.
05 L-PARM-RANGE PIC X(01).
05 L-PARM-YEAR1 PIC 9(04).
05 L-PARM-MONTH1 PIC 9(02).
05 L-PARM-DAY1 PIC 9(02).
05 L-PARM-YEAR2 PIC 9(04).
05 L-PARM-MONTH2 PIC 9(02).
05 L-PARM-DAY2 PIC 9(02).
*****************************************************************
* P R O C E D U R E D I V I S I O N *
*****************************************************************
PROCEDURE DIVISION USING L-INPUT-PARM.
MOVE L-PARM-MONTH1 TO W-MONTH.
IF W-VALID-MONTH
CONTINUE
ELSE
DISPLAY 'PLEASE ENTER VALID MONTH FOR DATE RANGE 1 '
STOP RUN
END-IF.
MOVE L-PARM-YEAR1 TO W-YEAR.
IF W-YEAR IS NUMERIC
CONTINUE
ELSE
DISPLAY 'PLEASE ENTER VALID YEAR FOR DATE RANGE YEAR1'
STOP RUN
END-IF.
IF L-PARM-RANGE = 'Y'
MOVE L-PARM-MONTH2 TO W-MONTH
IF W-VALID-MONTH
CONTINUE
ELSE
DISPLAY 'ENTER VALID MONTH FOR DATE RANGE 2 '
STOP RUN
END-IF
MOVE L-PARM-YEAR2 TO W-YEAR
IF W-YEAR IS NUMERIC
CONTINUE
ELSE
DISPLAY 'ENTER VALID YEAR FOR DATE RANGE YEAR2'
STOP RUN
END-IF
END-IF.
IF L-PARM-RANGE = 'Y' AND
W-RANGE-DATE1 NOT = SPACES AND
W-RANGE-DATE2 NOT = SPACES
DISPLAY 'RANGE ?? : YES'
PERFORM P0100-RANGE-PROCESSING
ELSE
IF W-RANGE-DATE1 NOT = SPACES
DISPLAY 'RANGE ?? : NO '
PERFORM P0200-DATE-PROCESSING
ELSE
DISPLAY 'PLEASE PROVIDE THE DATES FOR PROCESSING'
STOP RUN
END-IF
END-IF.
DISPLAY ' WEEKDAYS IN A MONTH ' A-WEEKDAY-COUNT.
DISPLAY ' WEEKEND DAYS IN MONTH ' A-WEEKDAY-SKIPPED.
STOP RUN.
*****************************************************************
* THIS CALCULATES THE WEEKDAYS BETWEEN THE TWO DATES *
*****************************************************************
P0100-RANGE-PROCESSING.
DISPLAY 'SUPPLIED YEAR1 : ' L-PARM-YEAR1.
DISPLAY 'SUPPLIED MONTH1 : ' L-PARM-MONTH1.
DISPLAY 'SUPPLIED DAY1 : ' L-PARM-DAY1.
DISPLAY 'SUPPLIED YEAR2 : ' L-PARM-YEAR2.
DISPLAY 'SUPPLIED MONTH2 : ' L-PARM-MONTH2.
DISPLAY 'SUPPLIED DAY2 : ' L-PARM-DAY2.
MOVE L-PARM-YEAR1 TO W-YEAR1.
MOVE L-PARM-MONTH1 TO W-MONTH1.
MOVE L-PARM-DAY1 TO W-DAY1.
MOVE L-PARM-YEAR2 TO W-YEAR2.
MOVE L-PARM-MONTH2 TO W-MONTH2.
MOVE L-PARM-DAY2 TO W-DAY2.
***START PROCESSING FROM DATE 1 UNTIL DATE1 > DATE2
MOVE W-RANGE-DATE1 TO W-DATE.
PERFORM P0110-PROCESS-DATE-RANGE
UNTIL W-RANGE-DATE1 > W-RANGE-DATE2.
*****************************************************************
* THIS CALCULATES WEEKDAYS IN A GIVEN DATE RANGE *
*****************************************************************
P0110-PROCESS-DATE-RANGE.
COMPUTE WS-INTEGER = FUNCTION
INTEGER-OF-DATE(W-DATE).
DIVIDE WS-INTEGER BY 7 GIVING WS-DIVIDE-ANSWER
REMAINDER WS-REMAINDER.
ADD +01 TO WS-REMAINDER.
EVALUATE WS-REMAINDER
WHEN 1
WHEN 7
ADD +01 TO A-WEEKDAY-SKIPPED
WHEN OTHER
ADD +01 TO A-WEEKDAY-COUNT
END-EVALUATE.
COMPUTE W-DATE =
FUNCTION DATE-OF-INTEGER
(FUNCTION INTEGER-OF-DATE (W-DATE) + 01).
MOVE W-DATE TO W-RANGE-DATE1.
*****************************************************************
* THIS CALCULATES THE WEEKDAYS IN A MONTH *
*****************************************************************
P0200-DATE-PROCESSING.
MOVE L-PARM-YEAR1 TO W-YEAR.
MOVE L-PARM-MONTH1 TO W-MONTH.
MOVE 01 TO W-DAY.
DISPLAY 'W-SYSTEM-DATE : ' W-SYSTEM-DATE(1:6).
PERFORM P0300-READ-END-DAY.
PERFORM P0400-CALCULATE-WEEKDAYS
WS-MAX-DAY-IN-MONTH TIMES.
*****************************************************************
* THIS WILL EXTRACT THE MAX NUMBER OF DAYS IN THE CURRENT MONTH *
* SUPPLIED *
*****************************************************************
P0300-READ-END-DAY.
EVALUATE TRUE
WHEN FUNCTION MOD (W-YEAR 4) NOT ZERO
WHEN FUNCTION MOD (W-YEAR 100) ZERO
AND FUNCTION MOD (W-YEAR 400) NOT ZERO
MOVE '28' TO C-TBL-MONTH-END (3: 2)
WHEN OTHER
MOVE '29' TO C-TBL-MONTH-END (3: 2)
END-EVALUATE.
MOVE TBL-MONTH-END-DAY(W-MONTH)
TO WS-MAX-DAY-IN-MONTH.
*****************************************************************
* THIS CALCULATES THE NUMBER OF WEEKDAYS IN A MONTH *
*****************************************************************
P0400-CALCULATE-WEEKDAYS.
MOVE W-SYSTEM-DATE TO W-DATE.
COMPUTE WS-INTEGER = FUNCTION
INTEGER-OF-DATE(W-DATE).
DIVIDE WS-INTEGER BY 7 GIVING WS-DIVIDE-ANSWER
REMAINDER WS-REMAINDER.
ADD +01 TO WS-REMAINDER.
EVALUATE WS-REMAINDER
WHEN 1
WHEN 7
ADD +01 TO A-WEEKDAY-SKIPPED
WHEN OTHER
ADD +01 TO A-WEEKDAY-COUNT
END-EVALUATE.
ADD +01 TO W-DAY.
|
Below are the results for the same:
Quote: | PARM SUPPLIED: N20040201
RANGE ?? : NO
W-SYSTEM-DATE : 200402
WEEKDAYS IN A MONTH 000000020
WEEKEND DAYS IN MONTH 000000009 |
Code: | IEF373I STEP/PS002 /START 2005006.1604
IEF374I STEP/PS002 /STOP 2005006.1605 CPU 0MIN 00.02SEC SRB |
Quote: | PARM SUPPLIED: N2004020120040706
RANGE ?? : NO
W-SYSTEM-DATE : 200402
WEEKDAYS IN A MONTH 000000020
WEEKEND DAYS IN MONTH 000000009 |
Code: | IEF373I STEP/PS002 /START 2005006.1606
IEF374I STEP/PS002 /STOP 2005006.1606 CPU 0MIN 00.02SEC SRB |
Quote: | PARM SUPPLIED: Y2003020120050106
RANGE ?? : YES
SUPPLIED YEAR1 : 2003
SUPPLIED MONTH1 : 02
SUPPLIED DAY1 : 01
SUPPLIED YEAR2 : 2005
SUPPLIED MONTH2 : 01
SUPPLIED DAY2 : 06
WEEKDAYS IN A MONTH 000000504
WEEKEND DAYS IN MONTH 000000202 |
Code: | IEF373I STEP/PS002 /START 2005006.1607
IEF374I STEP/PS002 /STOP 2005006.1607 CPU 0MIN 00.03SEC SRB |
I may be redundant somewhere.
Thanks a lot for your timely help......
Regs
OsCorp |
|
Back to top |
|
|
|
|