SAS Programming

DATA Step, Macro, Functions and more
BookmarkSubscribeRSS Feed
sas_coders
Calcite | Level 5

Hi,

 

I need to add 4 business days to a date, where i need to exclude the weekends and the U.S holidays, floated, or observed.

For eg : if i have a date : 08th Nov, 2018, it should return me 15th Nov2018.

 

Because as 11th Nov,2018 is a verteran day, which is on sunday the holiday moved to 12th Nov,2018

 

so my date is 08thNov,2018.

Day 1 : 09nov,2018

Day2 : 13nov,2018

Day3 : 14nov,2018

day4 : 15nov,2018

 

it should skip 10,11,12....as 10 is sat,11 is sunday, and 12 is a us holiday.

 

Please help.. 

14 REPLIES 14
Reeza
Super User
You have to create a custom calendar for yourself first and then you use that.

In general, INTNX() is used to increment/decrement dates.

See the solution from @EEng here:
https://communities.sas.com/t5/SAS-Programming/Finding-the-next-working-day-with-a-custom-calendar/t...
sas_coders
Calcite | Level 5

Hi,

 

Thanks for the reply.

But this solution doesnt work, because this solution is only checking if the initial date is equal to the holiday, if yes then skip that, but what if my next date is a holiday, it doesn't check that, as i said i need to add 4 business days.

 

Thanks,

Varun 

sas_coders
Calcite | Level 5

Hi, 

 

yes, by looking at this i was able to create the list of working and non working days, but now how to add 4 days in my dataset but looking at this data ?

 

Thanks

 

VDD
Ammonite | Level 13 VDD
Ammonite | Level 13
data _null_;
	xd = today();
	date1=input(put(xd,yymmdd8.),yymmdd8.);
 	datep4 = intnx('day',date1,+4);

put date1;
put datep4;
	format date1 date9. datep4 date9.;
run;

 

sas_coders
Calcite | Level 5

Need to remove the weekends and the holidays as well.

Reeza
Super User

Actually, the last example here is what you need:

https://documentation.sas.com/?docsetId=etsug&docsetTarget=etsug_intervals_sect008.htm&docsetVersion...

options intervalds=(BankingDays=BankDayDS);
data BankDayDS(keep=BEGIN);
   start = '15DEC1998'D;
   stop  = '15JAN2002'D;
   nwkdays = INTCK('WEEKDAY',start,stop);
   do i = 0 to nwkdays;
      BEGIN = INTNX('WEEKDAY',start,i);
      year = YEAR(BEGIN);
      if BEGIN ne HOLIDAY("NEWYEAR",year) and
         BEGIN ne HOLIDAY("MLK",year) and
         BEGIN ne HOLIDAY("USPRESIDENTS",year) and
         BEGIN ne HOLIDAY("MEMORIAL",year) and
         BEGIN ne HOLIDAY("USINDEPENDENCE",year) and
         BEGIN ne HOLIDAY("LABOR",year) and
         BEGIN ne HOLIDAY("COLUMBUS",year) and
         BEGIN ne HOLIDAY("VETERANS",year) and
         BEGIN ne HOLIDAY("THANKSGIVING",year) and
         BEGIN ne HOLIDAY("CHRISTMAS",year) then
      output;
   end;
   format BEGIN DATE.;
run;
data CountDays;
   start = '01JAN1999'D;
   stop  = '31DEC2001'D;
   ActualDays = INTCK('DAYS',start,stop);
   Weekdays   = INTCK('WEEKDAYS',start,stop);
   BankDays   = INTCK('BankingDays',start,stop);
   format start stop DATE.;
run;
title 'Methods of Counting Days';
proc print data=CountDays;
run;

They're using INTCK, you'll want INTNX() but that should be an easy switch.

 


@sas_coders wrote:

Need to remove the weekends and the holidays as well.



 

VDD
Ammonite | Level 13 VDD
Ammonite | Level 13

I gave you @sas_coders how to add 4 days to your date value.  you can use @Reeza link to determine if your date value is a holiday or such that needs that date values criteria changed.

 

sas_coders
Calcite | Level 5

okay, the point is while adding each day to my date, i need to check if that day is a holiday/weekend , if that is a holiday/weekend i need to start checking again, if not then add one more day and check if that is a holiday/weekend....untill 4 days are completed.

 

So, this won't work.

 

date1=input(put(xd,yymmdd8.),yymmdd8.);
 	datep4 = intnx('day',date1,+4);
Patrick
Opal | Level 21

@sas_coders 

Including holidays requires unfortunately a bit of extra coding. Below two links to two different approaches which you could make work for you with not much change required.

 

https://communities.sas.com/t5/SAS-Programming/exclude-holidays-from-the-count-of-days/td-p/358369 (accepted solution)

The main bit to change would be a definition of the date range for which you need a custom calendar.

do date = '01jan1971'd to '31dec2070'd ;

 

Or here the 2nd approach:

https://blogs.sas.com/content/sasdummy/2011/05/09/calculating-the-number-of-working-days-between-two...  

sas_coders
Calcite | Level 5

Hi,

 

Thank you for the reply.

 

But i do not want to count the number of Business days,i want to add 4 business days to my date.

That becomes little tough, as while adding single day to my date, i need to check if that is a holiday/weekend or not, if that is weekend/holiday continue adding untill 4 days, if it is not a weekend/holiday, add a day again and then repeat the process....untill 4 business days are added.

 

I hope my question is clear.

 

Thanks

 

Reeza
Super User

Your question is clear, but I think you're missing the point, the intervals and calculations needed to get the intervals set up is the same regardless for duration or increment - the underlying functions use the same definitions. 

So the linked answers should be relevant to what you're trying to do, and unfortunately this isn't simple, primarily because dates never are and different countries have different holidays and different companies treat holidays differently. So trying to find a single solution for everyone is impossible, and SAS has instead added the option to create your custom calendars. Creating that custom interval will solve your problem. 

 

Here's a solution that should work exactly as you need but I haven't tested it. Either way, should be a good start to getting you to where you need to be.

Good Luck. 

 

 

options intervalds=(BankingDays=BankDayDS);
data BankDayDS(keep=BEGIN);
   start = '01Jan2019'D;
   stop  = '31DEC2022'D;
   nwkdays = INTCK('WEEKDAY',start,stop);
   do i = 0 to nwkdays;
      BEGIN = INTNX('WEEKDAY',start,i);
      year = YEAR(BEGIN);
      if BEGIN ne HOLIDAY("NEWYEAR",year) and
         BEGIN ne HOLIDAY("MLK",year) and
         BEGIN ne HOLIDAY("USPRESIDENTS",year) and
         BEGIN ne HOLIDAY("MEMORIAL",year) and
         BEGIN ne HOLIDAY("USINDEPENDENCE",year) and
         BEGIN ne HOLIDAY("LABOR",year) and
         BEGIN ne HOLIDAY("COLUMBUS",year) and
         BEGIN ne HOLIDAY("VETERANS",year) and
         BEGIN ne HOLIDAY("THANKSGIVING",year) and
         BEGIN ne HOLIDAY("CHRISTMAS",year) then
      output;
   end;
   format BEGIN DATE.;
run;

data want;
set have;

new_date = intnx('BankingDays', date, 4);

run;

 

 


@sas_coders wrote:

Hi,

 

Thank you for the reply.

 

But i do not want to count the number of Business days,i want to add 4 business days to my date.

That becomes little tough, as while adding single day to my date, i need to check if that is a holiday/weekend or not, if that is weekend/holiday continue adding untill 4 days, if it is not a weekend/holiday, add a day again and then repeat the process....untill 4 business days are added.

 

I hope my question is clear.

 

Thanks

 


 

LeonidBatkhan
Lapis Lazuli | Level 10

There is a blog post where I show how to add or subtract a number of business days to a date. The approach described there should work in any country or any business or other jurisdiction that operates on its own workday calendar. It's based on dynamically creating a user-defined format listing days-off and workdays as OTHER category, and then creating a simple user-defined function or macro. Here is the blog link:

Shifting a date by a given number of workdays

Reeza
Super User
Any reason why you wouldn't create a custom calendar/interval that you could then call using INTNX()?

sas-innovate-white.png

Our biggest data and AI event of the year.

Don’t miss the livestream kicking off May 7. It’s free. It’s easy. And it’s the best seat in the house.

Join us virtually with our complimentary SAS Innovate Digital Pass. Watch live or on-demand in multiple languages, with translations available to help you get the most out of every session.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

SAS Training: Just a Click Away

 Ready to level-up your skills? Choose your own adventure.

Browse our catalog!

Discussion stats
  • 14 replies
  • 5386 views
  • 4 likes
  • 5 in conversation