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 

SORT to identify last business day of the month
Goto page Previous  1, 2
 
Post new topic   Reply to topic   printer-friendly view    MVSFORUMS.com Forum Index -> Utilities
View previous topic :: View next topic  
Author Message
Magesh_J
Intermediate


Joined: 21 Jun 2014
Posts: 259
Topics: 54

PostPosted: Fri Feb 14, 2020 4:31 pm    Post subject: Reply with quote

Hi Kolusu,

They left the 30th day in choice because the same logic is either handled on 28th or 29th or 30th or 31st (i.e when the indicator shows 'M').

So they don't need 30th to be marked as 'T'.

i.e each account is being reviewed three times in a month for a reporting purpose since they are reviewing it on month-end, the one or two days will not make any difference.

thanks
Magesh
Back to top
View user's profile Send private message
kolusu
Site Admin
Site Admin


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

PostPosted: Fri Feb 14, 2020 5:23 pm    Post subject: Reply with quote

Magesh_J,

Here are the alternate control cards

Code:

//SYSIN    DD *                                                         
  OPTION COPY,Y2PAST=2019                                               
  INREC IFOUTLEN=80,                                                   
          IFTHEN=(WHEN=INIT,                                             
         OVERLAY=(081:02,6,Y2W,LASTDAYM,TOGREG=Y2W,  $ MON LASTDATE     
                  091:81,6,Y2W,WEEKDAY=CHAR3,        $ LASTWDAY MON     
                  095:02,6,Y2W,WEEKDAY=CHAR3,        $ DAY OF WEEK       
                  098:05,1,CHANGE=(1,C'0',C'0',      $ HANDLE 10THDAY   
                                     C'8',C'8',      $ IF 10X IS WKND   
                                     C'9',C'9'),     $ 8 OR 9 IS FRI     
                      NOMATCH=(C' '),                                   
                  098:04,2,CHANGE=(1,C'28',C' ',     $ REMV 10X WKND     
                                     C'29',C' ',     $ PROCESSING FOR   
                                     C'30',C' ',     $ 28,29,30 & 31     
                                     C'31',C' '),                       
                      NOMATCH=(98,1),                                   
                  063:95,4,CHANGE=(2,C'FRI ',C'W ',  $ FRIDAY TAG       
                                     C'MON0',C'T',   $ 10X  DAY TAG     
                                     C'TUE0',C'T',   $ 10X  DAY TAG     
                                     C'WED0',C'T',   $ 10X  DAY TAG     
                                     C'THU0',C'T',   $ 10X  DAY TAG     
                                     C'FRI0',C'WT'   $ FRI+10X TAG       
                                     C'FRI8',C'WT',  $ ADV10X FRI TAG   
                                     C'FRI9',C'WT'), $ ADV10X FRI TAG   
                      NOMATCH=(C'  '))),                                 
                                                                         
  IFTHEN=(WHEN=(91,3,SS,EQ,C'SAT,SUN'),                                 
  OVERLAY=(081:81,6,Y2W,PREVDFRI,TOGREG=Y2W,         $ MON-END FRI       
           091:C'FRI'),HIT=NEXT),                                       
                                                                         
  IFTHEN=(WHEN=(02,6,CH,EQ,81,6,CH),                                     
  OVERLAY=(63:C'M ',                                 $ MON-END TAG       
           63:91,3,CHANGE=(2,C'FRI',C'WM'),          $ MON-END FRI       
                  NOMATCH=(63,2)))                   $ TAG               
                                                                         
/*                                                                       


If you want to tag the 30th dates then simply remove the 2nd change command

ie this piece of code

Code:

                  098:04,2,CHANGE=(1,C'28',C' ',     $ REMV 10X WKND     
                                     C'29',C' ',     $ PROCESSING FOR   
                                     C'30',C' ',     $ 28,29,30 & 31     
                                     C'31',C' '),                       
                      NOMATCH=(98,1),                                   

_________________
Kolusu - DFSORT Development Team (IBM)
DFSORT is on the Web at:
www.ibm.com/storage/dfsort

www.linkedin.com/in/kolusu
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Magesh_J
Intermediate


Joined: 21 Jun 2014
Posts: 259
Topics: 54

PostPosted: Fri Feb 14, 2020 5:43 pm    Post subject: Reply with quote

Thanks Kolusu, that's an awesome idea.

Regards,
Magesh
Back to top
View user's profile Send private message
kolusu
Site Admin
Site Admin


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

PostPosted: Fri Feb 14, 2020 7:32 pm    Post subject: Reply with quote

Nic Clouston wrote:
Hi Kolusu

I found the algorithm in a COBOL student book. This is my current Rexx version:


Nic,

I finally got around to test it a bit. Unfortunately this code only works for years 1900 to 2099. Any year before 1900 or years after 2099 , you get incorrect results.

I am validating it against this source

http://tlarsen2.tripod.com/thomaslarsen/easterdates.html

For example year 2100 , as per the rexx exec
Code:

IN 2100 EASTER SUNDAY WILL BE ON: MARCH 27


But according to "Astronomical Society of South Australia" it is on 28th March 2100, so we are off by 1 day

Here is another source that I used

https://www.wheniseastersunday.com/year/2100/
_________________
Kolusu - DFSORT Development Team (IBM)
DFSORT is on the Web at:
www.ibm.com/storage/dfsort

www.linkedin.com/in/kolusu
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Nic Clouston
Advanced


Joined: 01 Feb 2007
Posts: 1075
Topics: 7
Location: At Home

PostPosted: Sat Feb 15, 2020 6:55 am    Post subject: Reply with quote

That's OK - I'll be dead long before then! I only use it for my own purposes. i might, though, out of interest, see if I can find that text and check any caveats on it and search to see if I can get a more accurate algorithm.
_________________
Utility and Program control cards are NOT, repeat NOT, JCL.
Back to top
View user's profile Send private message
kolusu
Site Admin
Site Admin


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

PostPosted: Sat Feb 15, 2020 9:21 am    Post subject: Reply with quote

Nic Clouston wrote:
That's OK - I'll be dead long before then! I only use it for my own purposes. i might, though, out of interest, see if I can find that text and check any caveats on it and search to see if I can get a more accurate algorithm.


Nic,

The following seems to be working for all the years.

http://mathforum.org/library/drmath/view/52575.html
_________________
Kolusu - DFSORT Development Team (IBM)
DFSORT is on the Web at:
www.ibm.com/storage/dfsort

www.linkedin.com/in/kolusu
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Nic Clouston
Advanced


Joined: 01 Feb 2007
Posts: 1075
Topics: 7
Location: At Home

PostPosted: Mon Feb 17, 2020 5:03 am    Post subject: Reply with quote

Hmmm. I don't think it was that COBOL book. Trying other books but so far no luck. I did find that for years beginning 21 that there has to be an adjustment by +1 day - ditto for 18xx (-1) and -2 days for 17xx etc. There is a large and complex discussion on another 'forum' which I am going to try to understand.
_________________
Utility and Program control cards are NOT, repeat NOT, JCL.
Back to top
View user's profile Send private message
kolusu
Site Admin
Site Admin


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

PostPosted: Mon Feb 17, 2020 6:33 pm    Post subject: Reply with quote

Nic Clouston,

The math forum formula works and here is the DFSORT version for it

Code:

//**********************************************************************
//* Generate the input file for calculating easter for years 1700 thru *
//* 2299                                                               *
//**********************************************************************
//STEP0100 EXEC PGM=SORT                                               
//SYSOUT   DD SYSOUT=*                                                 
//SORTIN   DD *                                                         
ABC                                                                     
//SORTOUT  DD DSN=&&IN,DISP=(,PASS),SPACE=(TRK,(50,10),RLSE)           
//SYSIN    DD *                                                         
  OPTION COPY                                                           
  OUTFIL REPEAT=600,                                                   
          BUILD=(SEQNUM,4,ZD,START=1700)                               
/*
//**********************************************************************
//* from math forum :                                                  *
//* http://mathforum.org/library/drmath/view/52575.html                *
//*Below is shown the formula and its application to the year 1999     *
//*                                                                    *
//*If   k = Integer part of [T/100]            k = Int[1999/100] = 19  *
//*     a = T (mod 19)                         a = 1999 (mod 19) = 4   *
//*     b = T (mod 4)                          b = 1999 (mod 4) = 3    *
//*     c = T (mod 7)                          c = 1999 (mod 7) = 4    *
//*     q = Integer part of [k/4]              q = Int[19/4] = 4       *
//*     p = Integer part of [(13+8k)/25]       p = Int[165/25] = 6     *
//*     m = (15-p+k-q) (mod 30)                m = 24 (mod 30) = 24    *
//*     d = (19a + m) (mod 30)                 d = 100 (mod 30) = 10   *
//*     n = (4+k-q) (mod 7)                    n = 19 (mod 7) = 5      *
//*     e = (2b+4c+6d+n) (mod(7)               e = 87 (mod 7) = 3      *
//*                                                                    *
//*If  d+e <= 9  then  D = 22+d+e and M = 3    d+e = 10+3 = 13         *
//*                                                                    *
//*If  d = 29 and e = 6                                                *
//*              then  D = 19 and  M = 4       (not applicable here)   *
//*                                                                    *
//*If  d = 28 and e = 6 and a > 10                                     *
//*              then  D = 18 and  M = 4       (not applicable here)   *
//*                                                                    *
//*Otherwise  D = d+e-9  and  M = 4            D = 13-9 = 4,  M=4      *
//*                                                                    *
//*So Easter day in the year 1999 was on April 4th.                    *
//**********************************************************************
//STEP0200 EXEC PGM=SORT                                               
//SYSOUT   DD SYSOUT=*                                                 
//SORTIN   DD DISP=(OLD,DELETE),DSN=&&IN                               
//SORTOUT  DD SYSOUT=*
//SYSIN    DD *                                                 
  OPTION COPY                                                   
  INREC IFTHEN=(WHEN=INIT,                                     
         BUILD=(01:1,8)),                                       
        IFTHEN=(WHEN=INIT,                                     
       OVERLAY=(10:01,4,ZD,DIV,+100,EDIT=(TT),      $ k         
                13:01,4,ZD,MOD,+019,EDIT=(TT),      $ a         
                16:01,4,ZD,MOD,+004,EDIT=(TT),      $ b         
                19:01,4,ZD,MOD,+007,EDIT=(TT),      $ c         
                22:10,2,ZD,DIV,+004,EDIT=(TT),      $ q         
                25:(((10,2,ZD,MUL,+8),ADD,          $ p         
                      +13),DIV,+25),EDIT=(TT),                 
                28:((+15,SUB,25,2,ZD,ADD,           $ m         
                     10,2,ZD,SUB,22,2,ZD),                     
                     MOD,+30),EDIT=(TT),                       
                31:((13,2,ZD,MUL,+19),ADD,          $ d         
                     28,2,ZD),                                 
                     MOD,+30,EDIT=(TT),                         
                34:(+4,ADD,10,2,ZD,SUB,             $ n         
                    22,2,ZD),MOD,+07,EDIT=(TT),                 
                37:((+2,MUL,16,2,ZD),ADD,           $ e         
                    (+4,MUL,19,2,ZD),ADD,                       
                    (+6,MUL,31,2,ZD),ADD,                       
                     34,2,ZD),MOD,+07,EDIT=(TT),               
                40:31,2,ZD,ADD,37,2,ZD,EDIT=(TT))), $ d+e       
                                                               
        IFTHEN=(WHEN=(40,2,ZD,LE,9),                           
             OVERLAY=(43:C'03',                                 
                      46:(40,2,ZD,ADD,                         
                          +22),EDIT=(TT))),                     
                                                               
        IFTHEN=(WHEN=(31,2,ZD,EQ,29,AND,                       
                      37,2,ZD,EQ,06),                           
             OVERLAY=(43:C'04',                                 
                      46:C'19')),                               
                                                               
        IFTHEN=(WHEN=(31,2,ZD,EQ,28,AND,                 
                      37,2,ZD,EQ,06,AND,                 
                      13,2,ZD,GT,10),                   
             OVERLAY=(43:C'04',                         
                      46:C'18')),                       
                                                         
        IFTHEN=(WHEN=NONE,                               
             OVERLAY=(43:C'04',                         
                      46:(31,2,ZD,ADD,                   
                          37,2,ZD,SUB,                   
                         +09),EDIT=(TT)))               
                                                         
  OUTREC BUILD=(46,2,                                   
                46,2,CHANGE=(2,C'01',C'st',             
                               C'21',C'st',             
                               C'31',C'st',             
                               C'02',C'nd',             
                               C'22',C'nd',             
                               C'03',C'rd',             
                               C'23',C'rd'),             
                    NOMATCH=(C'th'),                     
                 X,                                     
                43,2,CHANGE=(6,C'03',C'March ',         
                               C'04',C'April '),         
                01,4,                                   
                17:X)                                   
/*

_________________
Kolusu - DFSORT Development Team (IBM)
DFSORT is on the Web at:
www.ibm.com/storage/dfsort

www.linkedin.com/in/kolusu
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Nic Clouston
Advanced


Joined: 01 Feb 2007
Posts: 1075
Topics: 7
Location: At Home

PostPosted: Tue Feb 18, 2020 10:39 am    Post subject: Reply with quote

And here is the updated Rexx version:
Code:
/*- Rexx ------------------------------------------------------------*/
/*                                                                   */
/* Name     : Easter.rex                       Mode : Interactive    */
/*                                                                   */
/* Author   : Nic Clouston                     Date : February 2020  */
/*                                                                   */
/* Function : Calculate the date of Easter Sunday for any given year */
/*                                                                   */
/* Input    : Keyboard                                               */
/*                                                                   */
/* Output   : Display of date on screen                              */
/*                                                                   */
/* from math forum :                                                 */
/*      http://mathforum.org/library/drmath/view/52575.html          */
/*  via https://www.mvsforums.com/helpboards/viewtopic.php?t=12986   */
/*                                                                   */
/*------------------------------------------------------------ Rexx -*/
Trace 'N'
/* Some constants */
OK    = 0
OOPS  = 28

/* Program version info */
pgm_version  = "10.0" /* OORexx */
this_program = "Easter.rex ("pgm_version")"

exit_msg  = this_program" has ended OK"
exit_code = OK
header = "----------------------- Easter Day Calculator -------------------"
   Parse Source os .
   If Abbrev(os,'W')
   Then os = "Win"

   Parse Arg year

   If year = ''
   Then exit_code = getYear()
   Else exit_code = editYear()
   If exit_code = OK
   Then Do
      Call doTheMath
        Call calcMonthAndDay
      Call displayResult
   End

end_pgm: NOP
   Say exit_msg

Exit edate
/*===================================================================*/
getYear:
/*-------------------------------------------------------------------*/
/* Prompt user for the year that Easter day is to be found for       */
/*-------------------------------------------------------------------*/
date_ok = 0

   Do While \date_ok

      If os = "Win"
      Then "CLS"
      Else If os = "TSO"
           Then "CLEAR"

      Say header
      Say
      Say "Enter year to calculate Easter day for in format ccyy"
      Say
      Pull year
      exit_code = editYear()
     
   End
   
end_getYear: NOP

Return exit_code
/*===================================================================*/
editYear:
/*-------------------------------------------------------------------*/
/* Prompt user for the year that Easter day is to be found for.      */
/*-------------------------------------------------------------------*/
   If Datatype(year, 'N') & Length(year) = 4
   Then Do
      date_ok = 1
      exit_code = OK
   End
   Else
      If ¬Datatype(year, 'N')
      Then Do
         exit_msg = "Error: Year must be numeric"
         exit_code = OOPS
      End
      Else Do
         exit_msg = "Error: Year must be 4 digits long"
         exit_code = OOPS
      End

end_getYear: NOP

Return exit_code
/*===================================================================*/
doTheMath:
/*-------------------------------------------------------------------*/
/*                                                                   */
/*-------------------------------------------------------------------*/
   k = Substr(year,1,2)
   a = year // 19
   b = year // 4
   c = year // 7
   q = k % 4
   p = (13 + (k * 8)) % 25
   m = (15 - p + k - q) // 30
   n = (4 + k - q) // 7
   d = ((19 * a) + m) // 30
   e = ((2 * b) + (4 * c) + (6 * d) + n) // 7

end_doTheMath: NOP

Return
/*===================================================================*/
calcMonthAndDay:
/*-------------------------------------------------------------------*/
/* From the result above calculate the month and day.                */
/*-------------------------------------------------------------------*/
   Select
      When d + e <= 9
      Then Do
         day = 22 + d + e
         month = "March"
      End

      When d = 29 && e = 6
      Then Do
         day = 19
         month = "April"
      End

      When d = 28 & e = 6 & a > 10
      Then Do
         day = 18
         month = "April"
      End
      Otherwise day = d + e - 9
         month = "April"
   End

   edate = month||' '||day

end_calcMonthAndDay: NOP

Return
/*===================================================================*/
displayResult:
/*-------------------------------------------------------------------*/
/* Start generating the output text according to the relation of this*/
/* year to the year being calculated.                                */
/*-------------------------------------------------------------------*/
   this_year = Substr(Date(S),1,4)
   If this_year < year
   Then time_word = "will be"
   Else If this_year = year
        Then time_word = "is"
        Else time_word = "was"
   text = "Easter Sunday "time_word" on:"
   If os = "Win"
   Then "CLS"
   Else If os = "TSO"
        Then "CLEAR"
   Say header
   Say
   Say "In "year text edate
   Say "***"
   Pull .

end_displayResult: NOP

Return

Edited to add windows/TSO screen clear code
_________________
Utility and Program control cards are NOT, repeat NOT, JCL.


Last edited by Nic Clouston on Wed Feb 19, 2020 4:01 pm; edited 1 time in total
Back to top
View user's profile Send private message
kolusu
Site Admin
Site Admin


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

PostPosted: Tue Feb 18, 2020 5:53 pm    Post subject: Reply with quote

Nic,

Thanks for the code. Couple of issues

1. "CLS" aka "Clear the screen"is not valid in TSO, it should "CLEAR" to do the same.

2. You have an erroneous character in the line 71 (before the Datatype)
Code:

  If ªDatatype(year, 'N')


3. Your endpgm exit should be using EXIT_CODE instead of EDATE

Code:

EXIT EXIT_CODE

instead of
Code:

Exit edate

_________________
Kolusu - DFSORT Development Team (IBM)
DFSORT is on the Web at:
www.ibm.com/storage/dfsort

www.linkedin.com/in/kolusu
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Nic Clouston
Advanced


Joined: 01 Feb 2007
Posts: 1075
Topics: 7
Location: At Home

PostPosted: Wed Feb 19, 2020 5:30 am    Post subject: Reply with quote

Ah.
Point 1 - this is rexx on a windows OS hence "CLS". I cut out a load of code that was related as I only use Windows. It is still in the original post.
2 - that would be the NOT symbol (¬) - code page stuff. I cannot edit the code now so could you change it for me please?
3 - I have edate because I have a test harness that calls the routine 100 times uses the date to draw out stats. It would also be used by anything calling the program to get the date.
_________________
Utility and Program control cards are NOT, repeat NOT, JCL.
Back to top
View user's profile Send private message
kolusu
Site Admin
Site Admin


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

PostPosted: Wed Feb 19, 2020 8:12 am    Post subject: Reply with quote

Nic Clouston wrote:

2 - that would be the NOT symbol (¬) - code page stuff. I cannot edit the code now so could you change it for me please?


Nic,

Done. I edited the post the reflect the ¬ sign. Btw I checked your profile and you are authorized to edit your posts, so unless you are in a rush or on a mobile device, I don't see the reason for you to not able to edit the posts.

Do you NOT see the button when viewing your posts?
_________________
Kolusu - DFSORT Development Team (IBM)
DFSORT is on the Web at:
www.ibm.com/storage/dfsort

www.linkedin.com/in/kolusu
Back to top
View user's profile Send private message Send e-mail Visit poster's website
Nic Clouston
Advanced


Joined: 01 Feb 2007
Posts: 1075
Topics: 7
Location: At Home

PostPosted: Wed Feb 19, 2020 10:13 am    Post subject: Reply with quote

I do see it but didn't look to see if I could - I thought I was only allowed to edit within 10 minutes of posting. Now tht it is mentioned I seem to vaguely remember that this was granted some eons ago in the past.

Anyway - thanks for doing that.

In fact, as I can do the edit myself I may add back the CLS/CLEAR coding.
_________________
Utility and Program control cards are NOT, repeat NOT, JCL.
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 -> Utilities All times are GMT - 5 Hours
Goto page Previous  1, 2
Page 2 of 2

 
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