IBM Mainframe Forum Index
 
Log In
 
IBM Mainframe Forum Index Mainframe: Search IBM Mainframe Forum: FAQ Register
 

And Tommy doesn't know what day it is...


IBM Mainframe Forums -> DFSORT/ICETOOL
Post new topic   Reply to topic
View previous topic :: View next topic  
Author Message
madmartinsonxx

New User


Joined: 10 Dec 2010
Posts: 96
Location: Massachusetts

PostPosted: Tue Apr 03, 2012 8:12 pm
Reply with quote

Hi,
We are currently working on a conversion from the legacy system to a client server application and we have been asked to provide test data that is future dated. Invoices, orders, inventory, benefits etc. the whole shooting match should look like it would in say 3 months to 10 months or so out. We took the dates ( several different formats ) and with ICETOOL converted them to the 8 byte format:

Code:

    Command ===>                                                        Scroll ===>    CSR
    ******    ***************************** Top of Data *****************************
    000001    20120427                                                               
    ******    **************************** Bottom of Data ***************************


What we are struggling with is that if we add 3 months, or longer timeframe, with the date functions of icetool to the dates we know we have a tight and correct date but are unsure whether this falls on a weekend or an american holiday. If the date does fall on one of the these anamolies we need either to subratct X number of days or add X number of days to ensure the scheduler, online systems and even weekely or monthly batch jobs we run do so in there usual lockstep. This one might be 'out there' but it is worth a new topic if it can be done. Thanks again.
Back to top
View user's profile Send private message
saiprasadh

Active User


Joined: 20 Sep 2006
Posts: 154
Location: US

PostPosted: Tue Apr 03, 2012 8:26 pm
Reply with quote

Can you provide some example along with RECFM & LRECL details
Back to top
View user's profile Send private message
Robert Sample

Global Moderator


Joined: 06 Jun 2008
Posts: 8696
Location: Dubuque, Iowa, USA

PostPosted: Tue Apr 03, 2012 8:49 pm
Reply with quote

For weekends, use Zeller's congruence.

For American holidays, you may have to write a program that uses a table of them since there's a lot of irregularity in them.
Back to top
View user's profile Send private message
Akatsukami

Global Moderator


Joined: 03 Oct 2009
Posts: 1788
Location: Bloomington, IL

PostPosted: Tue Apr 03, 2012 9:08 pm
Reply with quote

Robert Sample wrote:
For weekends, use Zeller's congruence.

For American holidays, you may have to write a program that uses a table of them since there's a lot of irregularity in them.

I agree that a little program to select from a holiday table is wanted. That being the case, the program might as well use LE or language-specific functions to get the weekday also.
Back to top
View user's profile Send private message
Frank Yaeger

DFSORT Developer


Joined: 15 Feb 2005
Posts: 7129
Location: San Jose, CA

PostPosted: Tue Apr 03, 2012 11:22 pm
Reply with quote

Kolusu is our DFSORT "date" expert. He's on vacation today, but I'll ask him to comment on this tomorrow when he gets back.
Back to top
View user's profile Send private message
don.leahy

Active Member


Joined: 06 Jul 2010
Posts: 765
Location: Whitby, ON, Canada

PostPosted: Tue Apr 03, 2012 11:38 pm
Reply with quote

Frank Yaeger wrote:
Kolusu is our DFSORT "date" expert. He's on vacation today, but I'll ask him to comment on this tomorrow when he gets back.
Adding business calendar functionality might be an interesting DFSORT enhancement. The DFSORT user would have to supply the local business calendar in some sort of standard format that DFSORT would use for various date manipulations. Lots of details to be worked out. icon_wink.gif
Back to top
View user's profile Send private message
madmartinsonxx

New User


Joined: 10 Dec 2010
Posts: 96
Location: Massachusetts

PostPosted: Tue Apr 03, 2012 11:39 pm
Reply with quote

don't shoot the messenger please
Back to top
View user's profile Send private message
Bill O'Boyle

CICS Moderator


Joined: 14 Jan 2008
Posts: 2501
Location: Atlanta, Georgia, USA

PostPosted: Tue Apr 03, 2012 11:57 pm
Reply with quote

Quote:
We are currently working on a conversion from the legacy system to a client server application


Unfortunate that this has to happen.... icon_sad.gif
Back to top
View user's profile Send private message
madmartinsonxx

New User


Joined: 10 Dec 2010
Posts: 96
Location: Massachusetts

PostPosted: Tue Apr 03, 2012 11:59 pm
Reply with quote

Unfortunate that this has to happen....

Agreed, but a 5 year gig will get me my RV icon_smile.gif
Back to top
View user's profile Send private message
Phrzby Phil

Senior Member


Joined: 31 Oct 2006
Posts: 1042
Location: Richmond, Virginia

PostPosted: Wed Apr 04, 2012 5:23 pm
Reply with quote

From your title, I suppose your real question is: How can you be saved?
Back to top
View user's profile Send private message
daveporcelan

Active Member


Joined: 01 Dec 2006
Posts: 792
Location: Pennsylvania

PostPosted: Wed Apr 04, 2012 5:34 pm
Reply with quote

Easy, just smash the mirror.
Back to top
View user's profile Send private message
Skolusu

Senior Member


Joined: 07 Dec 2007
Posts: 2205
Location: San Jose

PostPosted: Wed Apr 04, 2012 10:40 pm
Reply with quote

Robert Sample wrote:
For weekends, use Zeller's congruence.

For American holidays, you may have to write a program that uses a table of them since there's a lot of irregularity in them.


You don't have to use Zeller's congruence, as DFSORT has the WEEKDAY function which displays the Day of the week in 3 different formats.

And it is also easy to generate the common American holidays.


madmartinsonxx wrote:

What we are struggling with is that if we add 3 months, or longer timeframe, with the date functions of icetool to the dates we know we have a tight and correct date but are unsure whether this falls on a weekend or an american holiday. If the date does fall on one of the these anamolies we need either to subratct X number of days or add X number of days to ensure the scheduler, online systems and even weekely or monthly batch jobs we run do so in there usual lockstep. This one might be 'out there' but it is worth a new topic if it can be done. Thanks again.


madmartinsonxx,

It can be easily handled in DFSORT. With DFSORT's available Date functions you can validate and generate the common American holidays .


Common Public Holidays in USA
Code:

1. New Years (January 1st)
2. Martin Luther King, Jr Birthday (Third Monday in January)
3. Memorial Day (Last Monday in May)
4. Independence Day (July 4th)
5. Labor Day (First Monday in September)
6. Thanks Giving Day (Fourth Thursday in November)
7. Day After Thanks Giving
8. Christmas (December 25th)

If any of the holidays( New years, Independence Day, Christmas) fall on Saturday, then the previous Friday is declared as holiday. Here exception is new years. If it falls on Saturday, the previous Friday December 31st of prior year is a holiday. ex: January 1st 2011 falls on Saturday and in this case December 31st 2010 is declared as a holiday.

If any of the holidays( New years, Independence Day, Christmas) fall on Sunday, then the following Monday is declared as holiday.

It is easier to generate such holidays using the date functions of DFSORT considering all the scenarios mentioned above.

Code:

//STEP0100 EXEC PGM=SORT                                     
//SYSOUT   DD SYSOUT=*                                       
//SYMNAMES DD *                                               
NYR,S'&LYR4.0101'                                             
MLK,S'&LYR4.0101'                                             
MMD,S'&LYR4.0601'                                             
IDY,S'&LYR4.0704'                                             
LBD,S'&LYR4.0831'                                             
TGD,S'&LYR4.1031'                                             
CHD,S'&LYR4.1225'                                             
//*
//SORTIN   DD *                                               
DUMMY RECORD                                                 
//SORTOUT  DD DSN=&&S1,DISP=(,PASS),SPACE=(CYL,(1,0),RLSE)   
//SYSIN    DD *                                                   
  OPTION COPY                                                     
  INREC IFTHEN=(WHEN=INIT,                                         
  BUILD=(NYR,10:MLK,20:MMD,30:IDY,40:LBD,50:TGD,60:10X,70:CHD)),   
  IFTHEN=(WHEN=INIT,                                               
  OVERLAY=(10:10,8,Y4T,SUBDAYS,+1,TOGREG=Y4T,                     
           10:10,8,Y4T,NEXTDMON,TOGREG=Y4T,                       
           10:10,8,Y4T,ADDDAYS,+14,TOGREG=Y4T,                     
           20:20,8,Y4T,PREVDMON,TOGREG=Y4T,                       
           40:40,8,Y4T,NEXTDMON,TOGREG=Y4T,                       
           50:50,8,Y4T,NEXTDTHU,TOGREG=Y4T,                       
           50:50,8,Y4T,ADDDAYS,+21,TOGREG=Y4T,                     
           60:50,8,Y4T,ADDDAYS,+01,TOGREG=Y4T,                     
           81:01,8,Y4T,WEEKDAY=DIGIT1,                             
           82:30,8,Y4T,WEEKDAY=DIGIT1,                             
           83:70,8,Y4T,WEEKDAY=DIGIT1)),                           
                                                                   
  IFTHEN=(WHEN=(81,1,SS,EQ,C'1'),                                 
  OVERLAY=(01:01,8,Y4T,NEXTDMON,TOGREG=Y4T),HIT=NEXT),             
  IFTHEN=(WHEN=(82,1,SS,EQ,C'1'),                                 
  OVERLAY=(30:30,8,Y4T,NEXTDMON,TOGREG=Y4T),HIT=NEXT),             
  IFTHEN=(WHEN=(83,1,SS,EQ,C'1'),                                 
  OVERLAY=(70:70,8,Y4T,NEXTDMON,TOGREG=Y4T),HIT=NEXT),             
                                                                   
  IFTHEN=(WHEN=(82,1,SS,EQ,C'7'),                                 
  OVERLAY=(30:30,8,Y4T,PREVDFRI,TOGREG=Y4T),HIT=NEXT),             
  IFTHEN=(WHEN=(83,1,SS,EQ,C'7'),                                 
  OVERLAY=(70:70,8,Y4T,PREVDFRI,TOGREG=Y4T,                       
           90:70,8,Y4T,NEXTDFRI,TOGREG=Y4T))                       
                                                                   
  OUTFIL BUILD=(C'NEWYEARD,C''',01,8,C'''',/,                     
                C'MLKBDDAY,C''',10,8,C'''',/,                     
                C'MEMORDAY,C''',20,8,C'''',/,                     
                C'INDPDDAY,C''',30,8,C'''',/,                     
                C'LABORDAY,C''',40,8,C'''',/,                     
                C'THXGVDAY,C''',50,8,C'''',/,                     
                C'DAFTGDAY,C''',60,8,C'''',/,                     
                C'CHRISMAS,C''',70,8,C'''',/,                     
                C'NNEXTNYR,C''',90,8,C'''',80:X)                   
//*


This will generate 9 symbols as follows
Code:

NEWYEARD,C'20120102'
MLKBDDAY,C'20120116'
MEMORDAY,C'20120528'
INDPDDAY,C'20120704'
LABORDAY,C'20120903'
THXGVDAY,C'20121122'
DAFTGDAY,C'20121123'
CHRISMAS,C'20121225'
NNEXTNYR,C'        '


Now we will use the above symbols to validate the target date after adding the desired number of months or days (in this case 3 months).

Assuming this the input with sample dates
Code:

20120427
20120428
20120429
20120603


2012-04-27 + 3 months = 2012-07-27 which falls on Friday. so no need to increment the date

2012-04-28 + 3 months = 2012-07-28 which falls on Saturday. so increment the date by 2 days to get the next Monday which is 2012-07-30

2012-04-29 + 3 months = 2012-07-29 which falls on Sunday. so increment the date by 1 day to get the next Monday which is 2012-07-30

2012-06-03 + 3 months = 2012-09-03 which falls on Monday, however it is a labor day holiday, so increment the date by 1 day to get the next Tuesday which is 2012-09-04


Code:

//STEP0200 EXEC PGM=SORT                                         
//SYSOUT   DD SYSOUT=*                                           
//SYMNAMES DD DSN=&&S1,DISP=SHR                                 
//SORTIN   DD *                                                 
20120427                                                         
20120428                                                         
----+----1----+----2----+----3----+----4----+----5----+----6----+
20120603                                LABOR DAY SO INCREMENT 1
//SORTOUT  DD SYSOUT=*                                           
//SYSIN    DD *                                                 
  SORT FIELDS=COPY                                               
  INREC IFTHEN=(WHEN=INIT,                                       
  OVERLAY=(10:01,8,Y4T,ADDMONS,+3,TOGREG=Y4T,2X,                 
              10,8,Y4T,WEEKDAY=DIGIT1)),                         
  IFTHEN=(WHEN=(20,1,SS,EQ,C'1,7'),                             
  OVERLAY=(10:10,8,Y4T,NEXTDMON,TOGREG=Y4T),HIT=NEXT),           
  IFTHEN=(WHEN=(10,8,CH,EQ,NEWYEARD,OR,                         
                10,8,CH,EQ,MLKBDDAY,OR,                         
                10,8,CH,EQ,MEMORDAY,OR,                         
                10,8,CH,EQ,INDPDDAY,OR,                         
                10,8,CH,EQ,LABORDAY,OR,                         
                10,8,CH,EQ,THXGVDAY,OR,                         
                10,8,CH,EQ,DAFTGDAY,OR,                         
                10,8,CH,EQ,CHRISMAS,OR,                         
                10,8,CH,EQ,NNEXTNYR),                           
  OVERLAY=(10:10,8,Y4T,ADDDAYS,+1,TOGREG=Y4T))                   
//*


The output produced from this is

Code:

20120427 20120727  6                                           
20120428 20120730  7                                           
20120429 20120730  1                                           
20120603 20120904  2                    LABOR DAY SO INCREMENT 1
Back to top
View user's profile Send private message
Bill O'Boyle

CICS Moderator


Joined: 14 Jan 2008
Posts: 2501
Location: Atlanta, Georgia, USA

PostPosted: Wed Apr 04, 2012 11:48 pm
Reply with quote

Skolusu,

You and Frank provide some of the most outstanding answers and I don't think you're thanked enough, so this is mine to you both. icon_smile.gif

Regards,
Back to top
View user's profile Send private message
madmartinsonxx

New User


Joined: 10 Dec 2010
Posts: 96
Location: Massachusetts

PostPosted: Wed Apr 04, 2012 11:49 pm
Reply with quote

aye to that. the mirror was smashed......
Back to top
View user's profile Send private message
sqlcode1

Active Member


Joined: 08 Apr 2010
Posts: 577
Location: USA

PostPosted: Mon Apr 09, 2012 9:44 pm
Reply with quote

Skolusu,
Excellent solution. 2014.gif

Quote:
From Manual :- NEXTDday can be used to calculate the next specified day of the week for a date field.


Didn't know NEXTDday would stay there if the supplied date is the "day" itself.

Thanks,
Back to top
View user's profile Send private message
Skolusu

Senior Member


Joined: 07 Dec 2007
Posts: 2205
Location: San Jose

PostPosted: Mon Apr 09, 2012 9:59 pm
Reply with quote

sqlcode1 wrote:

Quote:
From Manual :- NEXTDday can be used to calculate the next specified day of the week for a date field.


Didn't know NEXTDday would stay there if the supplied date is the "day" itself.

Thanks,


I am not sure as to where you got that information but if the supplied date is the "day" itself and you want the NEXTDday, then it does get you to the next weekday.

For ex: today is Monday April 9th 2012 and using NEXTDMON on that date would result in Monday April 16th 2012.
Code:

//STEP0100 EXEC PGM=SORT                                   
//SYSOUT   DD SYSOUT=*                                     
//SORTIN   DD *                                             
                                                           
//SORTOUT  DD SYSOUT=*                                     
//SYSIN    DD *                                             
  SORT FIELDS=COPY                                         
  INREC OVERLAY=(01:DATE1,15:1,8,Y4T,NEXTDMON,TOGREG=Y4T)   
//*


The output from the above is
Code:

20120409      20120416
Back to top
View user's profile Send private message
Skolusu

Senior Member


Joined: 07 Dec 2007
Posts: 2205
Location: San Jose

PostPosted: Mon Apr 09, 2012 10:08 pm
Reply with quote

icon_redface.gif I just realized that there is a bug in second step where I am validating input file with the holidays. Can anyone pick that bug? icon_wink.gif
Back to top
View user's profile Send private message
sqlcode1

Active Member


Joined: 08 Apr 2010
Posts: 577
Location: USA

PostPosted: Mon Apr 09, 2012 11:31 pm
Reply with quote

Skolusu,
Quote:
I am not sure as to where you got that information but if the supplied date is the "day" itself and you want the NEXTDday, then it does get you to the next weekday.

I was lost in the way you calculated MLK and TGD. I didn't catch the lines where you subtracted 1 day from 20120101 to calculate MLK but you had used 20121031 while calculating TGD.

Quote:
I just realized that there is a bug in second step where I am validating input file with the holidays. Can anyone pick that bug?
It took me sometime to understand the solution and it will be premature for me to say its a bug so I am going to ask question. In the first step you would have already accounted for Saturday (subtract 1 day) and Sunday (add 1 day) to get to actual holiday but in step 2 you are going by Next Monday and then matching the value with holiday, which "probably" won't work. For example, if year is 2009 and input date is 20090403 the computed date comes to 20090704 which is 4th of July holiday.

I am having too many typos and misunderstandings today so I am not even going to attempt a solution icon_redface.gif icon_redface.gif icon_redface.gif but this solution is a keep for future requirements.

Thanks,
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Mon Apr 09, 2012 11:36 pm
Reply with quote

Meaning with New Year's day and Martin Luther King?
Back to top
View user's profile Send private message
sqlcode1

Active Member


Joined: 08 Apr 2010
Posts: 577
Location: USA

PostPosted: Mon Apr 09, 2012 11:44 pm
Reply with quote

Yes, when the holiday is certain day of certain week, he goes back to end of previous month and then goes to NEXTday(monday or thursday). Later he adds 14 and 21 days depending on holiday. I missed the part where he goes back differently for different holiday.

Like I said, that part is a total misunderstanding on my end.

Thanks,
Back to top
View user's profile Send private message
Skolusu

Senior Member


Joined: 07 Dec 2007
Posts: 2205
Location: San Jose

PostPosted: Mon Apr 09, 2012 11:54 pm
Reply with quote

sqlcode1 wrote:
It took me sometime to understand the solution and it will be premature for me to say its a bug so I am going to ask question. In the first step you would have already accounted for Saturday (subtract 1 day) and Sunday (add 1 day) to get to actual holiday but in step 2 you are going by Next Monday and then matching the value with holiday, which "probably" won't work. For example, if year is 2009 and input date is 20090403 the computed date comes to 20090704 which is 4th of July holiday.

I am having too many typos and misunderstandings today so I am not even going to attempt a solution icon_redface.gif icon_redface.gif icon_redface.gif but this solution is a keep for future requirements.

Thanks,


Well you are close , as the bug is when the holiday falls on a Friday, the logic would fail. I was simply adding 1 day if it is a holiday. So that would result in a saturday date which is a weekend. Also the same is the case with Thanks giving day. We need to get the NEXT monday for these dates and then validate to check if that monday is a holiday and then another day to it.

The conditions are

Code:

IF COMPUTED_DATE_DAY_OF_WEEK = 'SATURDAY'             OR   
   COMPUTED_DATE_DAY_OF_WEEK = 'SUNDAY'               OR   
   COMPUTED_DATE             = 'THANKS GIVING'        OR   
   COMPUTED_DATE             = 'DAY AFTER TG')             
                                                           
   INCREMENT THE DATE TO NEXT MONDAY                       
END-IF                                                     
                                                           
IF (COMPUTED_DATE             =  'NEW YEARS'           OR 
    COMPUTED_DATE             =  'INDEPENDENCE DAY'    OR 
    COMPUTED_DATE             =  'CHRISTMAS'           OR 
    COMPUTED_DATE             =  'NEW YEARS PREV DAY') AND
    COMPUTED_DATE_DAY_OF_WEEK =  'FRIDAY'                 
                                                           
   INCREMENT THE DATE TO NEXT MONDAY                       
END-IF                                                     


So the second step control cards should be

Code:

//SYSIN    DD *                                                 
  SORT FIELDS=COPY                                               
  INREC IFTHEN=(WHEN=INIT,                                       
  OVERLAY=(10:01,8,Y4T,ADDMONS,+3,TOGREG=Y4T,2X,                 
              10,8,Y4T,WEEKDAY=DIGIT1)),                         
  IFTHEN=(WHEN=(20,1,SS,EQ,C'1,7',OR,                           
               (10,8,CH,EQ,THXGVDAY,OR,10,8,CH,EQ,DAFTGDAY),OR, 
               (10,8,CH,EQ,NEWYEARD,OR,10,8,CH,EQ,INDPDDAY,OR,   
                10,8,CH,EQ,CHRISMAS,OR,10,8,CH,EQ,NNEXTNYR),AND,
                20,1,CH,EQ,C'6'),                                 
  OVERLAY=(10:10,8,Y4T,NEXTDMON,TOGREG=Y4T),HIT=NEXT),           
                                                                 
  IFTHEN=(WHEN=(10,8,CH,EQ,NEWYEARD,OR,                         
                10,8,CH,EQ,MLKBDDAY,OR,                         
                10,8,CH,EQ,MEMORDAY,OR,                         
                10,8,CH,EQ,INDPDDAY,OR,                         
                10,8,CH,EQ,LABORDAY,OR,                         
                10,8,CH,EQ,CHRISMAS),                           
  OVERLAY=(10:10,8,Y4T,ADDDAYS,+1,TOGREG=Y4T))                   
                                                                 
//*
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Tue Apr 10, 2012 4:33 am
Reply with quote

There was a little confusion with my earlier reply. I didn't notice sqlcode1's, which wasn't there when I started typing but was by the time I finished double-checking.

The problem is, after 1st October, any addition of three months takes you into the following year, yet the holidays set up (only Ney Year's Day and Martin Luther King's birthday are relevant for three months) are the wrong ones to check against.

With concordance I've attempted to resolve this.

The idea is to disturb Kolusu's code as little as possible (cos it is easier that way).

For the fanatics, I'm afraid this includes an extra step.

The idea is to generate the SYMNAMES Kolusu later uses. A "Starting Point" date is used for SORTIN, so that production of the dates does not rely on the sort being run on a particular day.

Instead of the full date for the model holidays, only the MMDD is used as constants in the step. The year from the Starting Point is pre-pended. If the MMDD of the holiday is less than the MMDD of the Starting Point, Starting-Point-Plus-One is the year used.

The output from this step is to go to the SYMNAMES DD of Kolusu's first step, with the DD * data for that step removed.

I've slightly amended the output from the second step to included the amended day number to make testing easier. I have "lightly" tested it.

Code:
//STEP0050 EXEC PGM=SORT
//SYSOUT   DD SYSOUT=*
//SYMNAMES DD *
STARTING-POINT,1,8,CH
 SP-YY,=,4,ZD
 SP-MMDD,*,4,CH
SP-YY-PLUS-ONE,80,4,CH
NYR-MMDD,C'0101'
MLK-MMDD,C'0101'
MMD-MMDD,C'0601'
IDY-MMDD,C'0704'
LBD-MMDD,C'0831'
TGD-MMDD,C'1031'
CHD-MMDD,C'1225'
//SYMNOUT DD SYSOUT=*
//*
//SORTIN   DD *
20121001 THIS IS THE "STARTING POINT" DATE
//SORTOUT  DD DSN=&&S0,DISP=(,PASS),SPACE=(CYL,(1,0),RLSE)
//SYSIN    DD *
  OPTION COPY
  INREC IFTHEN=(WHEN=INIT,
  OVERLAY=(10:SP-YY,NYR-MMDD,
         20:SP-YY,MLK-MMDD,
         30:SP-YY,MMD-MMDD,
         40:SP-YY,IDY-MMDD,
         50:SP-YY,LBD-MMDD,
         60:SP-YY,TGD-MMDD,
         70:SP-YY,CHD-MMDD,
         80:SP-YY,ADD,+1,TO=ZD,LENGTH=4)),
  IFTHEN=(WHEN=(14,4,CH,LT,SP-MMDD),
          OVERLAY=(10:SP-YY-PLUS-ONE),HIT=NEXT),
  IFTHEN=(WHEN=(24,4,CH,LT,SP-MMDD),
          OVERLAY=(20:SP-YY-PLUS-ONE),HIT=NEXT),
  IFTHEN=(WHEN=(34,4,CH,LT,SP-MMDD),
          OVERLAY=(30:SP-YY-PLUS-ONE),HIT=NEXT),
  IFTHEN=(WHEN=(44,4,CH,LT,SP-MMDD),
          OVERLAY=(40:SP-YY-PLUS-ONE),HIT=NEXT),
  IFTHEN=(WHEN=(54,4,CH,LT,SP-MMDD),
          OVERLAY=(50:SP-YY-PLUS-ONE),HIT=NEXT),
  IFTHEN=(WHEN=(64,4,CH,LT,SP-MMDD),
          OVERLAY=(60:SP-YY-PLUS-ONE),HIT=NEXT),
  IFTHEN=(WHEN=(74,4,CH,LT,SP-MMDD),
          OVERLAY=(70:SP-YY-PLUS-ONE))
                                                               
  OUTFIL BUILD=(C'NYR,C''',10,8,C'''',/,
                C'MLK,C''',20,8,C'''',/,
                C'MMD,C''',30,8,C'''',/,
                C'IDY,C''',40,8,C'''',/,
                C'LBD,C''',50,8,C'''',/,
                C'TGD,C''',60,8,C'''',/,
                C'CHD,C''',70,8,C'''',80:X)
//*
//STEP0100 EXEC PGM=SORT
//SYSOUT   DD SYSOUT=*
//SYMNAMES DD DSN=&&S0,DISP=(OLD,PASS)
//*
//SORTIN   DD *
DUMMY RECORD
//SORTOUT  DD DSN=&&S1,DISP=(,PASS),SPACE=(CYL,(1,0),RLSE)
//SYSIN    DD *
  OPTION COPY
  INREC IFTHEN=(WHEN=INIT,
  BUILD=(NYR,10:MLK,20:MMD,30:IDY,40:LBD,50:TGD,60:10X,70:CHD)),
  IFTHEN=(WHEN=INIT,
  OVERLAY=(10:10,8,Y4T,SUBDAYS,+1,TOGREG=Y4T,
           10:10,8,Y4T,NEXTDMON,TOGREG=Y4T,
           10:10,8,Y4T,ADDDAYS,+14,TOGREG=Y4T,
           20:20,8,Y4T,PREVDMON,TOGREG=Y4T,
           40:40,8,Y4T,NEXTDMON,TOGREG=Y4T,
           50:50,8,Y4T,NEXTDTHU,TOGREG=Y4T,
           50:50,8,Y4T,ADDDAYS,+21,TOGREG=Y4T,
           60:50,8,Y4T,ADDDAYS,+01,TOGREG=Y4T,
           81:01,8,Y4T,WEEKDAY=DIGIT1,
           82:30,8,Y4T,WEEKDAY=DIGIT1,
           83:70,8,Y4T,WEEKDAY=DIGIT1)),
                                                         
  IFTHEN=(WHEN=(81,1,SS,EQ,C'1'),
  OVERLAY=(01:01,8,Y4T,NEXTDMON,TOGREG=Y4T),HIT=NEXT),
  IFTHEN=(WHEN=(82,1,SS,EQ,C'1'),
  OVERLAY=(30:30,8,Y4T,NEXTDMON,TOGREG=Y4T),HIT=NEXT),
  IFTHEN=(WHEN=(83,1,SS,EQ,C'1'),
  OVERLAY=(70:70,8,Y4T,NEXTDMON,TOGREG=Y4T),HIT=NEXT),
                                                         
  IFTHEN=(WHEN=(82,1,SS,EQ,C'7'),
  OVERLAY=(30:30,8,Y4T,PREVDFRI,TOGREG=Y4T),HIT=NEXT),
  IFTHEN=(WHEN=(83,1,SS,EQ,C'7'),
  OVERLAY=(70:70,8,Y4T,PREVDFRI,TOGREG=Y4T,
           90:70,8,Y4T,NEXTDFRI,TOGREG=Y4T))
                                                         
  OUTFIL BUILD=(C'NEWYEARD,C''',01,8,C'''',/,
                C'MLKBDDAY,C''',10,8,C'''',/,
                C'MEMORDAY,C''',20,8,C'''',/,
                C'INDPDDAY,C''',30,8,C'''',/,
                C'LABORDAY,C''',40,8,C'''',/,
                C'THXGVDAY,C''',50,8,C'''',/,
                C'DAFTGDAY,C''',60,8,C'''',/,
                C'CHRISMAS,C''',70,8,C'''',/,
                C'NNEXTNYR,C''',90,8,C'''',80:X)
//*
//STEP0200 EXEC PGM=SORT
//SYSOUT   DD SYSOUT=*
//SYMNAMES DD DSN=&&S1,DISP=SHR
//SORTIN   DD *
20120427
20120428
20120603                                LABOR DAY SO INCREMENT 1
20120901
20121001                                NYD
20121021                                MLK
//SORTOUT  DD SYSOUT=*
//SYSIN    DD *
  SORT FIELDS=COPY
  INREC IFTHEN=(WHEN=INIT,
  OVERLAY=(10:01,8,Y4T,ADDMONS,+3,TOGREG=Y4T,2X,
              10,8,Y4T,WEEKDAY=DIGIT1)),
  IFTHEN=(WHEN=(20,1,SS,EQ,C'1,7',OR,
               (10,8,CH,EQ,THXGVDAY,OR,10,8,CH,EQ,DAFTGDAY),OR,
               (10,8,CH,EQ,NEWYEARD,OR,10,8,CH,EQ,INDPDDAY,OR,
                10,8,CH,EQ,CHRISMAS,OR,10,8,CH,EQ,NNEXTNYR),AND,
                20,1,CH,EQ,C'6'),
  OVERLAY=(10:10,8,Y4T,NEXTDMON,TOGREG=Y4T),HIT=NEXT),
                                                                 
  IFTHEN=(WHEN=(10,8,CH,EQ,NEWYEARD,OR,
                10,8,CH,EQ,MLKBDDAY,OR,
                10,8,CH,EQ,MEMORDAY,OR,
                10,8,CH,EQ,INDPDDAY,OR,
                10,8,CH,EQ,LABORDAY,OR,
                10,8,CH,EQ,CHRISMAS),
  OVERLAY=(10:10,8,Y4T,ADDDAYS,+1,TOGREG=Y4T),HIT=NEXT),
  IFTHEN=(WHEN=ANY,
  OVERLAY=(22:10,8,Y4T,WEEKDAY=DIGIT1)),
  IFTHEN=(WHEN=NONE,
  OVERLAY=(22:10,8,Y4T,WEEKDAY=DIGIT1))
                                                                 
//*


This should work for additions of up to one year less one day.
Back to top
View user's profile Send private message
vasanthz

Global Moderator


Joined: 28 Aug 2007
Posts: 1742
Location: Tirupur, India

PostPosted: Tue Apr 10, 2012 12:14 pm
Reply with quote

By any chance if you have SAS you could try something like,
Code:

year=2012;
Holiday_name = 'NEW YEAR';                                             
MDY_sas      = mdy(1,1,Year);                        /* JANUARY 1ST */ 
Wk_Day       = weekday(MDY_sas);                                       
if      Wk_Day = 7 then MDY_sas = MDY_sas - 1;/*-1 IF IT IS SATURDAY*/                       
else if wk_day = 1 then MDY_sas = MDY_sas + 1;  /*+1 IF IT IS SUNDAY*/                     
output;                                           

Holiday_name = 'MEMORIAL DAY';                                         
MDY_sas      = intnx('week.2',mdy(5,31,year),0); /* LAST MONDAY MAY */ 
output; 


or the HOLIDAY function in SAS 9.2(HOLIDAY function does not take into account if the holiday falls on saturday or sunday)
Code:
THANKSGIVING = holiday('thanksgiving', 2007);
easter = holiday('easter', 2007);


Hope it helps.
Back to top
View user's profile Send private message
Bill Woodger

Moderator Emeritus


Joined: 09 Mar 2011
Posts: 7309
Location: Inside the Matrix

PostPosted: Tue Apr 10, 2012 3:34 pm
Reply with quote

We are now back to two steps. For the solution, anyway. There is a new first step, for testing only. It generates 364 days starting from, and including, the date supplied on SYSIN. NB the date chosen should be the same as that used as the Starting Point for the holiday calendar. The SORTOUT is later input into the second step of the solution (the third here, everyone keeping up?).

That step has further minor amendments. The ANY/NONE combination has been replaced with OUTREC and a single WHEN=INIT, and there is some "self-testing" included. If a weekend is identified as the output date, the date is saved to the right and obliterated with XXXXXXXX. This has been tested by changing the 1,7 to 1,6.

The OUTFIL lists, for testing purposes only, all dates which had to be changed to get a working day. Remove the OUTFIL for generating required dates.

Code:
//GENEM EXEC PGM=SORT
//SORTOUT DD DSN=&&DAYSOUT,UNIT=SYSDA,SPACE=(CYL,1),DISP=(,PASS)
//SORTIN DD *
20120411
//SYSOUT DD SYSOUT=*
//SYSIN DD *
  SORT FIELDS=COPY
  OUTFIL REPEAT=364,
         IFTHEN=(WHEN=INIT,
                 OVERLAY=(10:SEQNUM,3,PD,START=0)),
         IFTHEN=(WHEN=INIT,
                 BUILD=(1,8,Y4T,ADDDAYS,10,3,PD,TOGREG=Y4T,80:X))
//STEP0100 EXEC PGM=SORT
//SYSOUT   DD SYSOUT=*
//SYMNAMES DD *
STARTING-POINT,1,8,CH
  SP-YY,=,4,ZD
  SP-MMDD,*,4,CH
SP-YY-PLUS-ONE,80,4,CH
NYR,10,8,CH
MLK,20,8,CH
MMD,30,8,CH
IDY,40,8,CH
LBD,50,8,CH
TGD,60,8,CH
CHD,70,8,CH
NYR-MMDD,C'0101'
MLK-MMDD,C'0101'
MMD-MMDD,C'0601'
IDY-MMDD,C'0704'
LBD-MMDD,C'0831'
TGD-MMDD,C'1031'
CHD-MMDD,C'1225'
//SYMNOUT DD SYSOUT=*
//SORTIN   DD *
20120411 THIS IS THE "STARTING POINT" DATE
//SORTOUT  DD DSN=&&S1,DISP=(,PASS),SPACE=(CYL,(1,0),RLSE)
//SYSIN    DD *
  OPTION COPY
  INREC IFTHEN=(WHEN=INIT,
                OVERLAY=(10:SP-YY,NYR-MMDD,
                         20:SP-YY,MLK-MMDD,
                         30:SP-YY,MMD-MMDD,
                         40:SP-YY,IDY-MMDD,
                         50:SP-YY,LBD-MMDD,
                         60:SP-YY,TGD-MMDD,
                         70:SP-YY,CHD-MMDD,
                         80:SP-YY,ADD,+1,TO=ZD,LENGTH=4)),
        IFTHEN=(WHEN=(14,4,CH,LT,SP-MMDD),
                OVERLAY=(10:SP-YY-PLUS-ONE),HIT=NEXT),
        IFTHEN=(WHEN=(24,4,CH,LT,SP-MMDD),
                OVERLAY=(20:SP-YY-PLUS-ONE),HIT=NEXT),
        IFTHEN=(WHEN=(34,4,CH,LT,SP-MMDD),
                OVERLAY=(30:SP-YY-PLUS-ONE),HIT=NEXT),
        IFTHEN=(WHEN=(44,4,CH,LT,SP-MMDD),
                OVERLAY=(40:SP-YY-PLUS-ONE),HIT=NEXT),
        IFTHEN=(WHEN=(54,4,CH,LT,SP-MMDD),
                OVERLAY=(50:SP-YY-PLUS-ONE),HIT=NEXT),
        IFTHEN=(WHEN=(64,4,CH,LT,SP-MMDD),
                OVERLAY=(60:SP-YY-PLUS-ONE),HIT=NEXT),
        IFTHEN=(WHEN=(74,4,CH,LT,SP-MMDD),
                OVERLAY=(70:SP-YY-PLUS-ONE))
                                                                 
  OUTREC IFTHEN=(WHEN=INIT,
  BUILD=(NYR,10:MLK,20:MMD,30:IDY,40:LBD,50:TGD,60:10X,70:CHD)),
  IFTHEN=(WHEN=INIT,
  OVERLAY=(10:10,8,Y4T,SUBDAYS,+1,TOGREG=Y4T,
           10:10,8,Y4T,NEXTDMON,TOGREG=Y4T,
           10:10,8,Y4T,ADDDAYS,+14,TOGREG=Y4T,
           20:20,8,Y4T,PREVDMON,TOGREG=Y4T,
           40:40,8,Y4T,NEXTDMON,TOGREG=Y4T,
           50:50,8,Y4T,NEXTDTHU,TOGREG=Y4T,
           50:50,8,Y4T,ADDDAYS,+21,TOGREG=Y4T,
           60:50,8,Y4T,ADDDAYS,+01,TOGREG=Y4T,
           81:01,8,Y4T,WEEKDAY=DIGIT1,
           82:30,8,Y4T,WEEKDAY=DIGIT1,
           83:70,8,Y4T,WEEKDAY=DIGIT1)),
                                                       
  IFTHEN=(WHEN=(81,1,SS,EQ,C'1'),
  OVERLAY=(01:01,8,Y4T,NEXTDMON,TOGREG=Y4T),HIT=NEXT),
  IFTHEN=(WHEN=(82,1,SS,EQ,C'1'),
  OVERLAY=(30:30,8,Y4T,NEXTDMON,TOGREG=Y4T),HIT=NEXT),
  IFTHEN=(WHEN=(83,1,SS,EQ,C'1'),
  OVERLAY=(70:70,8,Y4T,NEXTDMON,TOGREG=Y4T),HIT=NEXT),
                                                       
  IFTHEN=(WHEN=(82,1,SS,EQ,C'7'),
  OVERLAY=(30:30,8,Y4T,PREVDFRI,TOGREG=Y4T),HIT=NEXT),
  IFTHEN=(WHEN=(83,1,SS,EQ,C'7'),
  OVERLAY=(70:70,8,Y4T,PREVDFRI,TOGREG=Y4T,
           90:70,8,Y4T,NEXTDFRI,TOGREG=Y4T))
                                                       
  OUTFIL BUILD=(C'NEWYEARD,C''',01,8,C'''',/,
                C'MLKBDDAY,C''',10,8,C'''',/,
                C'MEMORDAY,C''',20,8,C'''',/,
                C'INDPDDAY,C''',30,8,C'''',/,
                C'LABORDAY,C''',40,8,C'''',/,
                C'THXGVDAY,C''',50,8,C'''',/,
                C'DAFTGDAY,C''',60,8,C'''',/,
                C'CHRISMAS,C''',70,8,C'''',/,
                C'NNEXTNYR,C''',90,8,C'''',80:X)
//*
//STEP0200 EXEC PGM=SORT
//SYSOUT   DD SYSOUT=*
//SYMNAMES DD DSN=&&S1,DISP=SHR
//SYMNOUT DD SYSOUT=*
//SORTIN   DD DSN=&&DAYSOUT,DISP=(OLD,PASS)
//SORTOUT  DD SYSOUT=*
//SYSIN    DD *
  SORT FIELDS=COPY
  INREC IFTHEN=(WHEN=INIT,
  OVERLAY=(10:01,8,Y4T,ADDMONS,+3,TOGREG=Y4T,2X,
              10,8,Y4T,WEEKDAY=DIGIT1)),
  IFTHEN=(WHEN=(20,1,SS,EQ,C'1,7',OR,
               (10,8,CH,EQ,THXGVDAY,OR,10,8,CH,EQ,DAFTGDAY),OR,
               (10,8,CH,EQ,NEWYEARD,OR,10,8,CH,EQ,INDPDDAY,OR,
                10,8,CH,EQ,CHRISMAS,OR,10,8,CH,EQ,NNEXTNYR),AND,
                20,1,CH,EQ,C'6'),
  OVERLAY=(10:10,8,Y4T,NEXTDMON,TOGREG=Y4T),HIT=NEXT),
                                                               
  IFTHEN=(WHEN=(10,8,CH,EQ,NEWYEARD,OR,
                10,8,CH,EQ,MLKBDDAY,OR,
                10,8,CH,EQ,MEMORDAY,OR,
                10,8,CH,EQ,INDPDDAY,OR,
                10,8,CH,EQ,LABORDAY,OR,
                10,8,CH,EQ,CHRISMAS),
  OVERLAY=(10:10,8,Y4T,ADDDAYS,+1,TOGREG=Y4T),HIT=NEXT)
  OUTREC IFTHEN=(WHEN=INIT,
  OVERLAY=(22:10,8,Y4T,WEEKDAY=DIGIT1)),
  IFTHEN=(WHEN=(22,1,SS,EQ,C'1,7'),
            OVERLAY=(24:1,8,01:C'XXXXXXXX'))
  OUTFIL INCLUDE=(20,1,CH,NE,22,1,CH,
               OR,01,1,CH,EQ,C'X',
               OR,22,1,SS,EQ,C'1,7')


I suspect further tweaks are possible, but I think it is serviceable.
Back to top
View user's profile Send private message
View previous topic :: :: View next topic  
Post new topic   Reply to topic View Bookmarks
All times are GMT + 6 Hours
Forum Index -> DFSORT/ICETOOL

 


Similar Topics
Topic Forum Replies
No new posts JES2 doesn't honor the priority of th... JCL & VSAM 8
No new posts No TSO prefix doesn't get the input CLIST & REXX 4
No new posts Sometimes Panel updates doesn't reflect TSO/ISPF 12
No new posts syncosrt doesn't recognize the digit JCL & VSAM 7
No new posts TWS OPC doesn't issue WTO when runnin... IBM Tools 6
Search our Forums:

Back to Top