Discussion:
Finding the nth business day of a given month and year
(too old to reply)
SAS Techies
2009-12-08 14:47:01 UTC
Permalink
This sample shows a macro version and the data step version that can
be used to find the nth business day of a given month and year.

This example uses the INTNX function to increment the date, time, or
datetime value by a given interval or intervals.
http://support.sas.com/onlinedoc/913/getDoc/en/lrdict.hlp/a000212700.htm

This macro is a modified version of the Source: http://support.sas.com/kb/37/632.html

/* This code creates the macro variable DAY that is the nth day of the
month.
The macro variable is in the SAS date format
*/

%macro test1
(checkday,month,year);
%global day;
%let date=%str(%'01)%upcase(%substr(&month,1,3))&year%str(%'d);
%put date=&date;

/*determine today's
date
%let date=%sysfunc(today
());
*/

%let
nthday=0;
%let
n=0;
%do %until
(&nthday=&checkday);
/* create a variable whose value is the first day of the
month*/
%let begin_month=%sysfunc(intnx(month,&date,
0,B));
/* increment the date by 1 day at a
time*/
%let day=%sysfunc(intnx
(day,&begin_month,&n));
/* determine the day of the
week*/
%let weekday=%sysfunc(weekday
(&day));
/* if the day of the week is not Saturday or Sunday then
increment
nthday plus
1*/
%if &weekday ne 7 and &weekday ne 1 %then %let nthday=%eval(&nthday
+1);
%let n=%eval(&n
+1);
%end;
/* checks the DAY macro variable by writing it to the log in the
DATE9.

format*/
%put %sysfunc(putn
(&day,date9.));
%mend;

%test1(5,SEP,
2010)


%macro test2
(checkday,month,year););
%global
day;
data
test;
date=input(compress('01'||substr("&month",1,3)||&year),date9.);

put date=;

nthday=0;

n=0;
do until
(nthday=&checkday);
begin_month=intnx('month',date,
0,'B');
day=intnx
('day',begin_month,n);
weekday=weekday
(day);
if weekday ne 7 and weekday ne 1 then nthday=nthday
+1;
n
+1;

end;
drop begin_month weekday date
n;
run;

proc
print;
format day
date9.;
run;

%mend;

%test2(8,april,2010)
Read more @ http://sastechies.blogspot.com/2009/12/finding-nth-business-day-of-month.html
Ian Whitlock
2009-12-10 03:17:11 UTC
Permalink
Summary: Teaching macro and SAS by example.
#iw-value=2

Perhaps the examples that SAS Techies used did not illustrate the
best teaching principles. The first macro operates in macro while
what one really wants is a macro to generate DATA step code to be
used in the users DATA step. The second generates a DATA step, but
it is not very usable in this form. As an example, there is little
reason for the macro.

Let's be specific. Generate code to act like a function in a
DATA step count the number of week days in a month up to the given
date. There ought to be a formula for this. We could use 3
quantities:

1) the number week days from the first week to the week
containing the given date
2) the number of week days missing from the first week
3) the number of week days missing from the last week

Then the total number of days is

5 * #weeks - #missing days in first week - #missing days in
the last week

Here is the code

%macro wkdays (cd) ;
%* return formula for number of weekdays from first of month ;
%local fd /* first day of month */ ;
%let fd = intnx("month",&cd,0,"B") ;

/* get number of whole weeks and subtract missing
days from first and last weeks and return formula
*/
( 5/7 * (&cd - weekday(&cd) - &fd + weekday(&fd) ) + 5
- max(0, (weekday(&fd) - 2)) - max(0, (6 - weekday(&cd))) )
%mend wkdays ;

Now the code can be used in any DATA step acting as a function.

/* test code using a month of every type
and 7 consecutive days starting in the first week
and 7 consecutive days starting in a later week
*/
data _null_ ;
retain cd numwkdays ;
format cd date9. ;
do month = 1, 2, 4, 5, 6, 8, 9 ;
put 40*"=" ;
do day = 1 to 7 , 20 to 26 ;
cd = mdy(month,day,2009) ;
numwkdays = %wkdays (cd) ;
put _all_ ;
end ;
end ;
run ;

Like the original, this code does not correct the fact that the
19th business day of this December is Christmas, but it does give
a one line formula for counting the number of week days including
Christmas.

Is it more efficient than looping? I don't know there are enough
function calls in the formula so that it may not be, but it is
technically more interesting. It illustrates one important way to
use macro. This cannot be said of the original macros. The best
that can be said for them is that if one needs an example using
looping and/or %SYSFUNC then it can be unearthed in these macros.

Ian Whitlock
=================

Date: Tue, 8 Dec 2009 06:47:01 -0800
From: SAS Techies <***@GMAIL.COM>
Subject: Finding the nth business day of a given month and year

This sample shows a macro version and the data step version that can
be used to find the nth business day of a given month and year.

This example uses the INTNX function to increment the date, time, or
datetime value by a given interval or intervals.
http://support.sas.com/onlinedoc/913/getDoc/en/lrdict.hlp/a000212700.htm

This macro is a modified version of the Source: http://support.sas.com/kb/37/632.html

/* This code creates the macro variable DAY that is the nth day of the
month.
The macro variable is in the SAS date format
*/

%macro test1
(checkday,month,year);
%global day;
%let date=%str(%'01)%upcase(%substr(&month,1,3))&year%str(%'d);
%put date=&date;

/*determine today's
date
%let date=%sysfunc(today
());
*/

%let
nthday=0;
%let
n=0;
%do %until
(&nthday=&checkday);
/* create a variable whose value is the first day of the
month*/
%let begin_month=%sysfunc(intnx(month,&date,
0,B));
/* increment the date by 1 day at a
time*/
%let day=%sysfunc(intnx
(day,&begin_month,&n));
/* determine the day of the
week*/
%let weekday=%sysfunc(weekday
(&day));
/* if the day of the week is not Saturday or Sunday then
increment
nthday plus
1*/
%if &weekday ne 7 and &weekday ne 1 %then %let nthday=%eval(&nthday
+1);
%let n=%eval(&n
+1);
%end;
/* checks the DAY macro variable by writing it to the log in the
DATE9.

format*/
%put %sysfunc(putn
(&day,date9.));
%mend;

%test1(5,SEP,
2010)


%macro test2
(checkday,month,year););
%global
day;
data
test;
date=input(compress('01'||substr("&month",1,3)||&year),date9.);

put date=;

nthday=0;

n=0;
do until
(nthday=&checkday);
begin_month=intnx('month',date,
0,'B');
day=intnx
('day',begin_month,n);
weekday=weekday
(day);
if weekday ne 7 and weekday ne 1 then nthday=nthday
+1;
n
+1;

end;
drop begin_month weekday date
n;
run;

proc
print;
format day
date9.;
run;

%mend;

%test2(8,april,2010)
Read more @ http://sastechies.blogspot.com/2009/12/finding-nth-business-day-of-month.html
Continue reading on narkive:
Loading...