在SAS宏变量中比较日期:为何IF语句未按预期执行?
SAS宏中日期比较IF语句未生效的原因及解决方法
问题根源
你当前的代码里,宏变量存储的是字符格式化后的日期字符串(通过mmddyy8.格式转换),而SAS宏的%if语句是按照字符串字典序来比较的,并非日期的实际逻辑大小。
举个实际例子:假设今天是2024年6月20日,三个宏变量的取值为:
&start_date=06/13/24&end_date=06/18/24&run_date=06/15/24
此时第一个%if能输出success是因为字符串"06/15/24"的字典序确实大于"06/13/24",但如果遇到跨月/跨年场景(比如start_date是12/25/23,run_date是01/02/24),字符串比较会得出"01/02/24" < "12/25/23"的错误结论,和实际日期大小完全相反。
两种解决方法
方法1:存储数值型日期(推荐)
SAS日期本质是数值(从1960年1月1日起的天数),直接存储数值型日期,宏里的%if就能按日期实际大小比较,需要展示格式时再转换:
%let start_date = %sysfunc(intnx(day,%sysfunc(today()),-7)); %let end_date = %sysfunc(intnx(day,%sysfunc(today()),-2)); %let run_date = %sysfunc(intnx(day,%sysfunc(today()),-5)); %put 格式化日期:%sysfunc(putn(&start_date,mmddyy8.)) %sysfunc(putn(&end_date,mmddyy8.)) %sysfunc(putn(&run_date,mmddyy8.)); %if &run_date > &start_date %then %do; %put success; %end; %if &run_date < &end_date %then %do; %put success; %end;
方法2:使用YYYYMMDD格式存储字符日期
如果必须存储字符型日期,改用yymmdd8.(或yymmdd10.)格式,这种格式的字符串字典序和日期逻辑大小完全一致:
%let start_date = %sysfunc(intnx(day,%sysfunc(today()),-7),yymmdd8.); %let end_date = %sysfunc(intnx(day,%sysfunc(today()),-2),yymmdd8.); %let run_date = %sysfunc(intnx(day,%sysfunc(today()),-5),yymmdd8.); %put &start_date &end_date &run_date; %if &run_date > &start_date %then %do; %put success; %end; %if &run_date < &end_date %then %do; %put success; %end;
内容的提问来源于stack exchange,提问作者intransigent_rocker
相关产品推荐
相关产品推荐

