BookmarkSubscribeRSS Feed
user112a2
Obsidian | Level 7

I need help on comparing two macro variable dates. Below is the code. You can see by the log that MINDT_AS_DATE_MINUS_ONE_DT1 is 23JUL2012 and TESTDT1 is 01JAN2013. However, when comparing SAS says 23JUL2012 <01JAN2013. is FALSE. I am very confused. Thanks

Removed

Not working in LOG, See:

Removed
6 REPLIES 6
Reeza
Super User

Because you're doing a text comparison. SAS doesn't recognize those values as dates.

 

You can either not use a format and compare the raw numbers within %EVAL or %SYSEVALF or you can use quotation marks and a D to make them date literals in the comparison.

 

Date literals:

%macro intermediate;
%if %sysevalf("&MINDT_AS_DATE_MINUS_ONE_DT1."d < "&TESTDT1."d) %then %do; 
	%PUT this is true;
%end;
%else %do;
	%PUT this is false;
%end;
%mend intermediate;

%intermediate;

No formats option:

 

%let TESTDT=2013-01-01;
%let TESTDT1=%sysfunc(inputn(&TESTDT, yymmdd10.));
%LET MINDT = 2012-07-23;
%LET MINDT_AS_DATE = %SYSFUNC(INPUTN(&MINDT., YYMMDD10.));
%LET MINDT_AS_DATE_MINUS_ONE = %SYSFUNC(INTNX(MONTHS, &MINDT_AS_DATE., -1));
%LET MINDT_AS_DATE_MINUS_ONE_DT = %SYSFUNC(INPUTN(&MINDT., YYMMDD10.));


data _null_;
MINDT_AS_DATE_MINUS_ONE_DT=&MINDT_AS_DATE_MINUS_ONE_DT.;
call symput('MINDT_AS_DATE_MINUS_ONE_DT1',MINDT_AS_DATE_MINUS_ONE_DT);
run;

@user112a2 wrote:

I need help on comparing two macro variable dates. Below is the code. You can see by the log that MINDT_AS_DATE_MINUS_ONE_DT1 is 23JUL2012 and TESTDT1 is 01JAN2013. However, when comparing SAS says 23JUL2012 <01JAN2013. is FALSE. I am very confused. Thanks

%let TESTDT=2013-01-01;
%let TESTDT1=%sysfunc(inputn(&TESTDT, yymmdd10.), date9.);
%LET MINDT = 2012-07-23;
%LET MINDT_AS_DATE = %SYSFUNC(INPUTN(&MINDT., YYMMDD10.));
%LET MINDT_AS_DATE_MINUS_ONE = %SYSFUNC(INTNX(MONTHS, &MINDT_AS_DATE., -1));
%LET MINDT_AS_DATE_MINUS_ONE_DT = %SYSFUNC(INPUTN(&MINDT., YYMMDD10.));
data _null_;
MINDT_AS_DATE_MINUS_ONE_DT=&MINDT_AS_DATE_MINUS_ONE_DT.;
call symput('MINDT_AS_DATE_MINUS_ONE_DT1',put(MINDT_AS_DATE_MINUS_ONE_DT,date9.));
run;
%macro intermediate;
%if &MINDT_AS_DATE_MINUS_ONE_DT1.<&TESTDT1. %then
%do; 
%PUT this is true;
%end;
%else 
%do;
%PUT this is false;
%end;
%mend intermediate;
%intermediate;

Not working in LOG, See:

SYMBOLGEN: Macro variable MINDT_AS_DATE_MINUS_ONE_DT1 resolves to 23JUL2012
SYMBOLGEN: Macro variable TESTDT1 resolves to 01JAN2013
MLOGIC(INTERMEDIATE): %IF condition &MINDT_AS_DATE_MINUS_ONE_DT1.<&TESTDT1. is FALSE
MLOGIC(INTERMEDIATE): %PUT this is false
this is false

 

user112a2
Obsidian | Level 7
Thanks!! Worked like a charm.
Astounding
PROC Star

Macro variables hold text, not numeric values.  So your comparison looks at the "2" at the beginning of "23JUL2012" and compares it to the "0" at the beginning of "01JAN2013".  Since "2" is greater than "0", the first date is larger than the second date.

 

To get macro language to make a numeric comparison, you could use:

 

%if %sysevalf("&MINDT_AS_DATE_MINUS_ONE_DT1"d) < %sysevalf("&TESTDT1"d) %then %do;

 

That translates the date expressions into numeric values on SAS's date scale.

 

@Reeza looks like you are 1 minute quicker than I am!

andreas_lds
Jade | Level 19

You don't compare dates, but the strings "23JUL2012" and "01JAN2013" and 2 has a higher value in the ASCII table than 0, so 23JUL2012 < 01JAN2013 is false.

 

If you explain what you want to achieve, i am sure that the community will find a solution that works well without macro-code.

 

EDIT: Well, i am to late again 😉

 

 

PaigeMiller
Diamond | Level 26

You can't use formatted dates in this command

 

%if &MINDT_AS_DATE_MINUS_ONE_DT1.<&TESTDT1. 

You would be much better off not formatting the data for use in macro evaluations, and in fact formatting the dates so they are readable by humans is wrong here. You could also create and do the test in your data _null_, resulting in much simpler code, no formatting needed, and in fact formatting is wrong here.

 

data _null_;
    testdt = '01JAN13'd;
    mindt = '23JUL12'd;
    ... additional functions as needed ...
run;

If you must do the work in a macro variable, it would look something like this (I have chosen to code up a simpler problem than the one you are working on as an example)

 

%let testdt = %sysfunc(inputn(2013-01-01,yymmdd10.)); /* Note: no formatting here to date9.) */
%let mindt = %sysfunc(inputn(2012-07-23,yymmdd10.)); /* Note: no formatting here to date9. */

/* Do comparison */
%if &mindt < &testdt %then %put this is true;
%else %put this is false;

 

--
Paige Miller
Tom
Super User Tom
Super User

Looks like it is working to me. The digit 2 is larger than the digit 0 in the lexical ordering of strings.

If you want SAS to treat those as dates you could convert them to date literals, but then you would need to use %SYSEVALF() if you wanted the macro processor to understand them.

1741  %let MINDT_AS_DATE_MINUS_ONE_DT1=23JUL2012;
1742  %let TESTDT1=01JAN2013;
1743  %IF %sysevalf("&MINDT_AS_DATE_MINUS_ONE_DT1"d < "&TESTDT1"d) %then %do;
1744    %put TRUE;
TRUE
1745  %end;
1746  %else %do;
1747    %put FALSE;
1748  %end;

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 6 replies
  • 5189 views
  • 5 likes
  • 6 in conversation