Above example 1/31 and 2/28 12/31 marked as M - meaning month-end last business day, this was done manually.
The goal is if month-end falls on a weekend the M indicator has to advance to last business day of the month, in the above example, Feb 29 falls on Saturday and hence moved to 28th Feb.
I tried writing a sort not getting an idea if this not possible then I will write Cobol.
Joined: 15 Dec 2009 Posts: 12 Topics: 0 Location: Atlanta
Posted: Wed Feb 12, 2020 5:47 pm Post subject:
If you download the Smart DFSORT Tricks paper from https://www.ibm.com/support/pages/smart-dfsort-tricks you can find code to provide the weekday for a date; you can also find out how to subtract days from a date. The two of these, combined, should provide what you need. Note, however, that if the last business day of the month is actually a holiday (as does happen every now and then), there is no way DFSORT (or any other sort package) can know about the holiday. If this is a concern, writing code in the language of your choice might be the best solution since you can take into account the holiday schedule.
Joined: 26 Nov 2002 Posts: 12376 Topics: 75 Location: San Jose
Posted: Wed Feb 12, 2020 6:41 pm Post subject: Re: SORT to identify last business day of the month
Magesh_J wrote:
Is it possible to identify the last business day of the month using Sort.
Above example 1/31 and 2/28 12/31 marked as M - meaning month-end last business day, this was done manually.
The goal is if month-end falls on a weekend the M indicator has to advance to last business day of the month, in the above example, Feb 29 falls on Saturday and hence moved to 28th Feb.
I tried writing a sort not getting an idea if this not possible then I will write Cobol.
Thanks
Magesh
Magesh,
What happens if the LAST FRIDAY of the month is also a holiday? For example the day after Thanks giving. In 2030 Thanksgiving day is Thursday , November 28 and Friday November 29th is a holiday. In that case would you go back to using Novemeber 27th as the Last business day?
Also do you have the dates already generated, or do you need to generate it for every year? _________________ Kolusu
www.linkedin.com/in/kolusu
Joined: 26 Nov 2002 Posts: 12376 Topics: 75 Location: San Jose
Posted: Wed Feb 12, 2020 6:42 pm Post subject:
Robert Sample wrote:
If you download the Smart DFSORT Tricks paper from https://www.ibm.com/support/pages/smart-dfsort-tricks you can find code to provide the weekday for a date; you can also find out how to subtract days from a date. The two of these, combined, should provide what you need. Note, however, that if the last business day of the month is actually a holiday (as does happen every now and then), there is no way DFSORT (or any other sort package) can know about the holiday. If this is a concern, writing code in the language of your choice might be the best solution since you can take into account the holiday schedule.
Robert,
The only day that can happen to be a holiday is the day after thanks giving. None of the other last day of the month dates are official holidays (at least in USA) and that is easy to handle. I already mentioned the Thanksgiving holiday issue in 2030. In 2030 Thanksgiving day is Thursday , November 28 and Friday November 29th is a holiday. _________________ Kolusu
www.linkedin.com/in/kolusu
Joined: 26 Nov 2002 Posts: 12376 Topics: 75 Location: San Jose
Posted: Wed Feb 12, 2020 7:37 pm Post subject:
Magesh,
I went ahead and coded a job to generate the dates for a year that you can pass as a parm. It does some validation YEAR > 0 and YEAR <= 9999 and then generates the dates for that year along with tagging the last business day of the month. It does even handle the thanks giving day issue.
Code:
// EXPORT SYMLIST=*
// SET GENYEAR=2030
//***************************************************************
//* CREATE SYMBOLS TO GENERATE THE DATES FOR THE YEAR PASSED *
//* CHECK THE DDNAME PRINT IN CASE THIS STEP RETURNS AN RC=4 *
//***************************************************************
//STEP0100 EXEC PGM=SORT
//SYSOUT DD SYSOUT=*
//SORTIN DD *
ABC
//SORTOUT DD DSN=&&S,DISP=(,PASS),SPACE=(TRK,(1,0))
//PRINT DD SYSOUT=*
//SYSIN DD *,SYMBOLS=JCLONLY
OPTION COPY,STOPAFT=1
INREC IFOUTLEN=80,
IFTHEN=(WHEN=INIT,BUILD=(C'*0101',C'&GENYEAR')),
IFTHEN=(WHEN=(6,4,UFF,GT,0,AND,
6,4,UFF,LE,9999),
OVERLAY=(12:02,08,Y4W,LASTDAYY,TOGREG=Y4W,
22:12,08,Y4W,DATEDIFF,02,08,Y4W,
32:22,08,SFF,ADD,+1,M11,LENGTH=3)),
IFTHEN=(WHEN=NONE,
OVERLAY=(35:C'INVALID YEAR'))
OUTFIL FNAMES=PRINT
/*
//***************************************************************
//* GENERATE THE DATES FOR THE YEAR PASSED AND TAG THE LAST *
//* FRIDAY OF THE MONTH AS THE BUSINESS DAY *
//* EXCEPTIONS TO THIS RULE IS THE DAY AFTER THANKSGIVING DAY *
//* EXAMPLE : THANKSGIVING IN 2030 IS NOVEMBER 28TH AND FRIDAY *
//* NOVEMBER 29TH IS A HOLIDAY AND SINCE NOVEMBER 30TH*
//* IS SATURDAY WE TAG THE DAY BEFORE THANKSGIVING AS *
//* I.E WEDNESDAY NOVEMBER 27TH AS THE LAST BUSINESS *
//* OF THE MONTH. *
//***************************************************************
//STEP0200 EXEC PGM=SORT,COND=(0,NE)
//SYSOUT DD SYSOUT=*
//SYMNAMES DD DISP=(OLD,DELETE),DSN=&&S
//SYMNOUT DD SYSOUT=*
//SORTIN DD *
ABC
//SORTOUT DD SYSOUT=*
//SYSIN DD *,SYMBOLS=JCLONLY
OPTION COPY,STOPAFT=1
OUTFIL REPEAT=NUMDAYS,
IFOUTLEN=80,
IFTHEN=(WHEN=INIT,
OVERLAY=(001:C'*0101',C'&GENYEAR',
081:SEQNUM,3,ZD,START=0,
002:02,8,Y4W,ADDDAYS,81,3,ZD,TOGREG=Y4W,
085:02,8,Y4W,LASTDAYM,TOGREG=Y4W,
095:85,8,Y4W,WEEKDAY=CHAR3,
099:2,2,CHANGE=(4,C'11',C'1031'),
NOMATCH=(C' '),
103:99,1,CHANGE=(4,C' ',C' '),
NOMATCH=(6,4))),
Joined: 01 Feb 2007 Posts: 1075 Topics: 7 Location: At Home
Posted: Thu Feb 13, 2020 5:25 am Post subject:
Note that, although irrelevant to Magesh's scenario, Good Friday may also be a holiday in some jurisdictions and otherwise be the last business day.
I used to have a PL/1 program that did all the holidays and business days for the UK but it will be out of date now - holidays moved/added. Easy-peasy in Rexx. _________________ Utility and Program control cards are NOT, repeat NOT, JCL.
Joined: 26 Nov 2002 Posts: 12376 Topics: 75 Location: San Jose
Posted: Thu Feb 13, 2020 12:16 pm Post subject:
Nic Clouston wrote:
Note that, although irrelevant to Magesh's scenario, Good Friday may also be a holiday in some jurisdictions and otherwise be the last business day.
Nic,
How did you manage the Good Friday calculation ? Varying equinox dates and Paschal Full Moon date? I would really appreciate if you can share the logic to calculate Good Friday Date? _________________ Kolusu
www.linkedin.com/in/kolusu
Joined: 01 Feb 2007 Posts: 1075 Topics: 7 Location: At Home
Posted: Thu Feb 13, 2020 5:28 pm Post subject:
Hi Kolusu
I found the algorithm in a COBOL student book. This is my current Rexx version:
Code:
/*- Rexx -------------------------------------------------------------*/
/* */
/* Project : Tools */
/* */
/* Name : EASTER Mode : Interactive */
/* */
/* Author : Nic Clouston Date : December 1996 */
/* */
/* Function : Calculate the date of Easter Sunday for any given year */
/* */
/* Input : Keyboard */
/* */
/* Output : Display of date on screen */
/* */
/*------------------------------------------------------------- Rexx -*/
Trace 'N'
/* Some constants */
TRUE = 1
FALSE = 0
OK = 0
OOPS = 28
/* Program version info */
pgm_version = "1.0"
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"
title = header os
Parse Arg year
If year = ''
Then Call GetYear
Call createOutputTextStart
Call doTheMath
Call calcMonthAndDay
If os = "Win"
Then "CLS"
Else If os = "TSO"
Then "CLEAR"
Say title
Say
Say "In "year text edate
Say "***"
Pull .
end_pgm: NOP
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 title
Say
Say "Enter year to calculate Easter day for in format ccyy"
Say
Pull year
If Datatype(year,'N')
Then If Length(year) = 4
Then date_ok = 1
Else Do
Say
Say "Error: Year must be 4 digits long"
Say "Press <Enter> key"
Pull .
End
Else Do
Say
Say "Error: Year must be numeric"
Say "Press <Enter> key"
Pull .
End
End
Return
/*===================================================================*/
createOutputTextStart:
/*-------------------------------------------------------------------*/
/* 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 text = "Easter Sunday will be on:"
Else If this_year = year
Then text = "Easter Sunday is on:"
Else text = "Easter Sunday was on:"
Return
/*===================================================================*/
doTheMath:
/*-------------------------------------------------------------------*/
/* Do the calculations. I got them from a COBOL book. There is no */
/* explanation for the calculations. */
/*-------------------------------------------------------------------*/
a = year // 19
b = year // 4
c = year // 7
d = (19 * a + 24) // 30
e = ((2 * b) + (4 * c) + (6 * d) + 5) // 7
day = d + e + 22
Return
/*===================================================================*/
calcMonthAndDay:
/*-------------------------------------------------------------------*/
/* From the result above calculate the month and day. */
/*-------------------------------------------------------------------*/
If day <= 31
Then month = "March"
Else Do
month = "April"
day = day - 31
If e = 6
Then If d = 29
Then day = 19
Else If (d = 28 & a > 10)
Then day = 18
End
edate = month||' '||day
Return
_________________ Utility and Program control cards are NOT, repeat NOT, JCL.
Thank you very much for the code, After testing I realized there are other indicators also involved.
1. Weekly - Every Friday
2. Ten-day - Every 10th day
if weekly and 10th day falls on the same day, the indicator should 'WT'
if Friday alone and not 10th day then indicator should be 'W'
if 10th day is not Friday then indicator should be 'T'
if 10th days fall on the weekend, then the indicator should advance to Friday.
if month-end falls on Friday then 'WM'
Also, I realized the date in position 2,8 MMDDYYYY
The actual input file looks like this.
Code:
input file looks like this
***************************** Top of Data ******************
----+----1----+----2----+----3----+----4----+----5----+----6
***************************** Top of Data ******************
*01012121001 2021
*01022121002 2021
*01032121003 2021
*01042121004 2021
*01052121005 2021
*01062121006 2021
*01072121007 2021
*01082121008 2021
*01092121009 2021
*01102121010 2021
*01112121011 2021
*01122121012 2021
*01132121013 2021
*01142121014 2021
*01152121015 2021
*01162121016 2021
*01172121017 2021
I missed noticing this, also the indicator needs to be set up in the 63rd position, with the help of your code, I tried doing the same logic for the tenth day and weekly indicator.
IFTHEN=(WHEN=(04,02,CH,LE,C'10'), -- 10TH DAY
OVERLAY=(107:95,2,C'10',
99,4,115:107,8,Y4W,WEEKDAY=CHAR3),HIT=NEXT),
IFTHEN=(WHEN=(04,02,CH,GT,C'10',AND, -- 20TH DAY
04,02,CH,LE,C'20'),
OVERLAY=(107:95,2,C'20',99,4,
115:107,8,Y4W,WEEKDAY=CHAR3),
HIT=NEXT),
*** -- ADV TO PREVFRI
IFTHEN=(WHEN=(115,3,SS,EQ,C'SAT,SUN'), -- FOR 10 TH DAY
OVERLAY=(107:107,8,Y4W,PREVDFRI,TOGREG=Y4W),HIT=NEXT),
Joined: 26 Nov 2002 Posts: 12376 Topics: 75 Location: San Jose
Posted: Fri Feb 14, 2020 12:26 pm Post subject:
Magesh_J wrote:
Hi Kolusu,
Thank you very much for the code, After testing I realized there are other indicators also involved.
1. Weekly - Every Friday
2. Ten-day - Every 10th day
if weekly and 10th day falls on the same day, the indicator should 'WT'
Magesh,
If you need to tag every 10th day, why not the 30th ? For example July 30 2020 is a Thursday and July 31st 2020 is a Friday. So shouldn't you be tagging July 30 2020 as "T" and July 31 2020 as "WM" ?
Magesh_J wrote:
Also, I realized the date in position 2,8 MMDDYYYY
You do realize that you can do the date calculations even on Y2x dates? In your case you can use Y2W format. Something like this
Code:
02,6,Y2W,LASTDAYM,TOGREG=Y2W
You just need to adjust your Y2past value. If you have Y2PAST=2010 then your CENTURY WINDOW FOR Y2 FORMAT FIELDS IS FROM 2010 TO 2109
Magesh_J wrote:
The actual input file looks like this.
I missed noticing this, also the indicator needs to be set up in the 63rd position, with the help of your code, I tried doing the same logic for the tenth day and weekly indicator.
Please advise, if I am missing or overdoing anything.
Again sorry !!!, I should have given these requirements in the first request.
Regards,
Magesh
Well you are a member for a long time, and it is a rookie mistake of not telling the entire requirements. Either way, I think the control cards can be optimized.
Let me know the rule for handling 30th and also the DCB properties of the input and output files. _________________ Kolusu
www.linkedin.com/in/kolusu
If you need to tag every 10th day, why not the 30th ? For example July 30 2020 is a Thursday and July 31st 2020 is a Friday. So shouldn't you be tagging July 30 2020 as "T" and July 31 2020 as "WM" ?
30th they didn't consider it as 'T' because they are handling the logic through 'M' every month end.
kolusu wrote:
You just need to adjust your Y2past value. If you have Y2PAST=2010 then your CENTURY WINDOW FOR Y2 FORMAT FIELDS IS FROM 2010 TO 2109
This I learned today, thanks, then we can use Y2W itself because we are going to do it for a future date only we never gonna execute this for a past date.
kolusu wrote:
Well you are a member for a long time, and it is a rookie mistake of not telling the entire requirements
Kolusu wrote:
Let me know the rule for handling 30th and also the DCB properties of the input and output files.
Joined: 26 Nov 2002 Posts: 12376 Topics: 75 Location: San Jose
Posted: Fri Feb 14, 2020 2:43 pm Post subject:
Magesh_J wrote:
30th they didn't consider it as 'T' because they are handling the logic through 'M' every month end.
Magesh_J,
Not quite right as I have shown the example of July 30 2020 and July 31 2020. You will run into such instances with all the months that 31 days (Jan, Mar,May, July, Aug, Oct and Dec) _________________ Kolusu
www.linkedin.com/in/kolusu
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