SAS全球日期比较

时间:2015-08-11 02:31:10

标签: sas

我试图进行日期比较,但我没有得到正确的结果。有谁知道发生了什么?

%macro ttt;
    %let check_start = 28APR2014;
    %if "&check_start."d < "25may2014"d %then %let true = 1;
    %else %if "&check_start."d > "25may2014"d %then %let true = 2;
    %put &true;
%mend;
%ttt;

14         %macro ttt;
15          %let check_start = 28APR2010;
16          %if "&check_start."d < "25may2014"d %then %let true = 1;
17          %else %if "&check_start."d > "25may2014"d %then %let true = 2;
18          %put &true;
19          %mend;
20          %ttt;
true = 2

宏变量true应等于1

2 个答案:

答案 0 :(得分:5)

在这种情况下,您需要使用%sysevalf()来评估比较。以下作品。

%macro ttt;
    %let check_start = 28APR2015;
    %if %sysevalf("&check_start"d < '25may2014'd) %then %let true=1;
    %else %if %sysevalf("&check_start."d > '25may2014'd) %then %let true=2;
    %put &true.;
%mend;
%ttt;

答案 1 :(得分:2)

Reeza提供了一个很好的解决方案,但我想我也会添加一些建议。

您遇到的问题是我建议在使用宏语言时不要使用日期文字的原因。相反,日期文字(即"01jan2000"d)我建议使用包含日期值的宏变量(即%let start_of_21st_century = %sysfunc(mdy(1,1,2000));)。通过使用宏变量,您不仅可以避免上述问题,而且还可以自行记录代码。

目前我不知道您的代码在2014年5月25日有什么意义,但是如果你有这一行:

%let product_launch_date = %sysfunc(mdy(5,25,2014));

......那么任何读它的人都会清楚其重要性。

您的代码将成为:

%macro ttt;
    %local check_start compare_date;

    %let check_start = %sysfunc(mdy(4,28,2014));
    %let compare_date = %sysfunc(mdy(5,25,2014));

    %if &check_start < &compare_date %then %let true = 1;
    %else %if &check_start > &compare_date %then %let true = 2;

    %put &true;
%mend;

还有一些我认为会改变的事情。我注意到的一件事是,如果2个日期值相等,则不会为true分配值。所以这应该可以补救。

此外,在SAS中,典型的真/假概念通常表示如下:

  • 值为零表示FALSE
  • 任何非零数字(包括底片)代表TRUE

因此,如果一个名为true的宏变量值为1或2(这两个值通常表示值为true)可能会让某些人感到困惑。我会考虑重命名宏变量,或使用值0和1(或其他非零数字)。

结合所有这些,宏将变成类似:

%macro check_dates;
    %local check_start compare_date;

    %let check_start = %sysfunc(mdy(4,28,2014));
    %let compare_date = %sysfunc(mdy(5,25,2014));

    %let check_start_compared_higher = &check_start > &compare_date;

    %if &check_start_compared_higher %then %do;
      %put It was higher =) ;
    %end;
    %else %do;
      %put It was equal to or lower =( ;
    %end;
%mend;
%check_dates;

对最终宏的一些评论......名为true的宏变量已被替换为名为check_start_compared_higher的更具描述性的变量。因为我们只需要一个存储在其中的布尔值,我们可以简单地为它分配评估表达式&check_start > &compare_date的结果,它将返回0(如果为假)或1(如果为真)。这比使用%if...%else...语句进行赋值更容易阅读,因为很明显代码行只是执行赋值而已。

%if &check_start_compared_higher %then %do;显示了我们如何使用新保存的值来控制程序流。因为&check_start_compared_higher中的值解析为TRUE或FALSE,所以我们可以通过这种方式轻松地使用它来生成易于读取的if语句。