MVSFORUMS.com Forum Index MVSFORUMS.com
A Community of and for MVS Professionals
 
 FAQFAQ   SearchSearch   Quick Manuals   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

Calculate Weekdays in a month

 
Post new topic   Reply to topic   printer-friendly view    MVSFORUMS.com Forum Index -> Application Programming
View previous topic :: View next topic  
Author Message
OSCORP
Beginner


Joined: 15 Oct 2004
Posts: 29
Topics: 8

PostPosted: Tue Jan 04, 2005 2:03 pm    Post subject: Calculate Weekdays in a month Reply with quote

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
View user's profile Send private message
kolusu
Site Admin
Site Admin


Joined: 26 Nov 2002
Posts: 12375
Topics: 75
Location: San Jose

PostPosted: Tue Jan 04, 2005 5:13 pm    Post subject: Reply with quote

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
View user's profile Send private message Send e-mail Visit poster's website
OSCORP
Beginner


Joined: 15 Oct 2004
Posts: 29
Topics: 8

PostPosted: Tue Jan 04, 2005 7:21 pm    Post subject: Reply with quote

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
View user's profile Send private message
kolusu
Site Admin
Site Admin


Joined: 26 Nov 2002
Posts: 12375
Topics: 75
Location: San Jose

PostPosted: Tue Jan 04, 2005 9:34 pm    Post subject: Reply with quote

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
View user's profile Send private message Send e-mail Visit poster's website
kolusu
Site Admin
Site Admin


Joined: 26 Nov 2002
Posts: 12375
Topics: 75
Location: San Jose

PostPosted: Tue Jan 04, 2005 9:36 pm    Post subject: Reply with quote

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
View user's profile Send private message Send e-mail Visit poster's website
OSCORP
Beginner


Joined: 15 Oct 2004
Posts: 29
Topics: 8

PostPosted: Tue Jan 04, 2005 11:49 pm    Post subject: Reply with quote

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
View user's profile Send private message
kolusu
Site Admin
Site Admin


Joined: 26 Nov 2002
Posts: 12375
Topics: 75
Location: San Jose

PostPosted: Wed Jan 05, 2005 6:24 am    Post subject: Reply with quote

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
View user's profile Send private message Send e-mail Visit poster's website
OSCORP
Beginner


Joined: 15 Oct 2004
Posts: 29
Topics: 8

PostPosted: Thu Jan 06, 2005 4:23 pm    Post subject: Reply with quote

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
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic   printer-friendly view    MVSFORUMS.com Forum Index -> Application Programming All times are GMT - 5 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


MVSFORUMS
Powered by phpBB © 2001, 2005 phpBB Group