我有以下代码:
%if "&min_date"dt <= "02DEC2014:00:00:00"dt %then %do;
/* some code */
%end
它并没有像我期望的那样表现。
我的min_date
较差,但测试的表达式评估为0
%put &min_date; /* 31JAN1600:00:00:00 */
%put %eval("&min_date"dt <= "02DEC2014:00:00:00"dt); /* 0 */
%put %eval("31JAN1600:00:00:00"dt <= "02DEC2014:00:00:00"dt); /* 0 */
我如何使这项工作?
答案 0 :(得分:1)
如您所示,%EVAL不知道日期时间文字,因此它将它们视为字符串值。由于%EVAL由%IF语句隐式调用。 %IF语句进行文本比较而不是数字比较。
好消息是%SYSEVALF 确实了解日期时间文字:
%let min_date = 31JAN1600:00:00:00 ;
%put %sysevalf("&min_date"dt) ; /*-11357884800*/
%put %sysevalf("&min_date"dt <= "02DEC2014:00:00:00"dt); /* 1 */
%put %sysevalf("31JAN1600:00:00:00"dt <= "02DEC2014:00:00:00"dt); /* 1 */
在宏%IF中:
%macro test(min_date=) ;
%if %sysevalf("&min_date"dt <= "02DEC2014:00:00:00"dt) %then %do;
%put &min_date is less than or equal to "02DEC2014:00:00:00"dt ;
%end ;
%else %do ;
%put &min_date is NOT less than or equal to "02DEC2014:00:00:00"dt ;
%end ;
%mend ;
返回日志,如:
124 %test(min_date=31JAN1600:00:00:00)
31JAN1600:00:00:00 is less than or equal to "02DEC2014:00:00:00"dt
125 %test(min_date=31JAN2015:00:00:00)
31JAN2015:00:00:00 is NOT less than or equal to "02DEC2014:00:00:00"dt
答案 1 :(得分:1)
实际上,%EVAL()在您的示例中“有效”。 :)不是预期的,但这就是原因:
首先,%EVAL()检查操作数是否可以计算为算术(仅整数)或逻辑。
因为您提供了2个包含非整数字符的日期时间文字,所以它根据字符排序顺序执行了逻辑比较。
%SYSEVALF() - 如前所述 - 将起作用,因为与%EVAL()不同,它支持非整数字符作为操作数并进行额外评估。
%SYSEVALF()支持浮点运算,而%EVAL()只支持整数。
BTW,%EVAL()也用于评估%IF或%DO语句中的表达式等 - 这就是为什么在这些情况下也不支持datetime文字。
注意:考虑到上述情况,通常的好习惯是:
其中x将根据日期时间字面值而变化...
答案 2 :(得分:0)
即使您正在使用文字,我认为宏环境会将要比较的值视为字符串 - 它不会尝试在执行比较之前将文字解析为基础数值。如果您希望比较按预期工作,则必须将日期转换为宏语言可以比较的数字,例如
。%put %eval(%sysfunc(putn("&min_date"dt,16.)) <= %sysfunc(putn("02DEC2014:00:00:00"dt,16.)));
或者,您可以暂时退出宏语言,然后可以直接使用文字,例如:
%put %eval(%sysfunc(intck(second,"&min_date"dt,"02DEC2014:00:00:00"dt)) > 0);