2015-02-24 51 views
1

所以,我想找到某一天前的第五个工作日,这意味着不包括周末和银行假期。在一个正常的星期,它似乎工作正常,但如果我尝试07APR2015的开始日期,这是复活节周五,周末和复活节星期一之后的星期二,它将返回错误的第五天。如何让这个功能正常工作?这是在复活节周末给我错误的日子

TXT文件包含:

bhol 
01jan2015 
03apr2015 
06apr2015 
04may2015 
25may2015 
31aug2015 
25dec2015 
28dec2015 

的代码如下:

options mprint mlogic symbolgen; 

proc import out=bhols datafile="C:\Users\me\Documents\bhols.txt" dbms=csv replace; 
label; 
run; 

data bholdates; 
    set bhols; 
    sasdate=input(bhol,date9.); 
    today=input("07apr2015",date9.); 
    weekday=weekday(today); 
    call symputx("todayd",today,"g"); 
run; 

proc sql ; 
    select sasdate into :bhols separated by " " 
    from bholdates; 
quit; 

%macro five; 
data test; 
/* format today day day5 date9.;*/ 
    retain count; 
    count=0; 
    today=&todayd; 
    day=&todayd-1; 
    do until(count=1); 
    weekday=weekday(day); 
    if day in(&bhols) or weekday in(1,7) then do; 
    day=day-1; 
    end; 
    if day not in(&bhols) and weekday not in(1,7) then do; 
    count=count+1; 
    weekday5=weekday(day); 
    day5=day; 
    day=day-1; 
    end; 
    end; 
run; 
%mend; 
%five; 

我希望变量DAY5以包含指定日期前第五个工作日。

+0

你会考虑创建自己的自定义时间间隔吗?如果你有一个文件和SAS 9.3+的假期,这是一个不错的选择,那么你可以使用intck/intnx函数。 – Reeza 2015-02-25 04:57:44

回答

1

我会尝试这样的事:

/* Step back 5 days */ 
do i = 1 to 5; 
    day - 1; 
    /* Step back an extra day for each weekend or bank holiday encountered */ 
    do while(weekday(day) in (1, 7) or day in (&bhols.)); 
    day - 1; 
    end; 
end; 

do i = 1 to 5将通过工作日退一步,和do while()将确保你跨过所有的周末和节假日,即使他们是相邻的。

0

最简单的方法(我这样做一个相当数量)是找到所有不是周末和假期的日期。在你的价值之前查找价值5。

/*All weekdays in the year*/ 
data not_hols; 
format date date9.; 
do date="01JAN2015"d to "31DEC2015"d; 
    if weekday(date) not in (6,7) then 
     output; 
end; 
run; 

/*Delete the holidays*/ 
proc sql noprint; 
delete from not_hols 
where date in (select bhols from bhols); 
quit; 

/*Add an index*/ 
data not_hols; 
set not_hols; 
index = _n_; 
run; 

/*Date to find*/ 
%let find_dt=07apr2015; 

/*Look up the date based on the index being -5 from the value of 
    find_dt */ 
proc sql noprint; 
select date format date9. 
    into :back5 
from not_hols 
where index = (
    select index-5 
    from not_hols 
    where date = "&find_dt"d 
); 
quit; 

%put Back 5 from &find_dt = &back5; 

创建NOT_HOLS数据的第一部分可一次完成,并保存在一个永久的位置。然后,您可以使用SQL在需要时获取所需的日期。