Hi! Can you please help me create a macro that always prints yesterday's date in SAS Date please?
I tried the following:
data _null_;
call symput('yesterday', put(intnx('day', today(), -1), ddyyyy10.));
run;
%put &yesterday;
But I get the following error: Format DDYYYY was not found or could not be loaded.
There is no such format.
Any valid format should work. Alphabetic list of valid DATE or DATETIME or TIME formats:
Be sure to choose a DATE format.
Also, if you are going to perform arithmetic or logical operations with this macro variable, you would be better off not formatting it. See Maxim 28.
That would work if you are planning to use the data for arithmetic or logical operations. If you want it to appear in human readable form like for titles or labels, then you need it formatted.
Use CALL SYMPUTX
I need to use it for some filters. We need to do datepart(dateX) > yesterdaydate and datepart(dateX) <= dateY
When I do datepart(dateX) and get a SAS Date, so that's why I need all other dates to be also in the format of SAS Date.
For the DateY I'm doing the following:
proc sql;
select DateY format ddyyyy10.
into :DateY
from DE.TRACK
where TABLE = "TRACK";
quit;
Is there a more correct way to do it?
@InêsMaximiano wrote:
I need to use it for some filters. We need to do datepart(dateX) > yesterdaydate and datepart(dateX) <= dateY
When I do datepart(dateX) and get a SAS Date, so that's why I need all other dates to be also in the format of SAS Date.
Incorrect. SAS does all comparisons on unformatted values. Even if the date looks to you as 01JAN2025 (this is a formatted date), SAS still uses the unformatted date when it does arithmetic or comparisons.
Example:
data fakedata;
date='01JAN2025'd;
output;
date='26FEB2026'd;
output;
format date date9.;
run;
This code correctly finds the dates before yesterday
data _null_; /* UNFORMATTED DATE IN MACRO VARIABLE */
call symputx('yesterday',intnx('day',today(),-1));
run;
data want;
set fakedata;
if date<&yesterday;
run;
This code with a formatted date produces errors
data _null_; /* FORMATTED DATE IN MACRO VARIABLE */
call symputx('yesterday',put(intnx('day',today(),-1),date9.));
run;
data want;
set fakedata;
if date<&yesterday;
run;
Use unformatted date values in your macro variables, as I show in the examples above.
@InêsMaximiano wrote:
I saw the examples now! Thank you so much!
One last question, how can I get DateY
from the table DE.TRACK, but removing the format?
You don't have to change the variables in a SAS data set. You can leave them alone. It works fine if they are formatted. It works fine if they are unformatted. Why? Because SAS always works with unformatted values for arithmetic and logical operations.
Macro variables are different, they will usually not work formatted for arithmetic and logical operations (without additional effort).
@InêsMaximiano wrote:
I need to use it for some filters. We need to do
datepart(dateX) > yesterdaydate and datepart(dateX) <= dateY
...
I assume you want to replace the yesterdaydate in that formula?
So you can put there anything that evaluates to a valid date.
So either a formula, like TODAY()-1, or a date literal, like '25FEB2025'd, or just the actual number of days since 1960 that such a date literal represents, like 23797. Or even compare the datatime value to a datetime literal instead.
Some examples:
datepart(dateX) > (today()-1) and datepart(dateX) <= dateY
datepart(dateX) > (intnx('day',today(),-1)) and datepart(dateX) <= dateY
datepart(dateX) > '25FEB2025'd and datepart(dateX) <= dateY
datepart(dateX) > "25FEB2025"d and datepart(dateX) <= dateY
datepart(dateX) > 23797 and datepart(dateX) <= dateY
dateX >= "26FEB2025:00:00"dt and datepart(dateX) <= dateY
PS Unless there is a need to include leading and/or trailing spaces in the macro variable you should be using the normal CALL SYMPUTX() method and not the ancient CALL SYMPUT() method.
@InêsMaximiano wrote:
I need to use it for some filters. We need to do datepart(dateX) > yesterdaydate and datepart(dateX) <= dateY
When I do datepart(dateX) and get a SAS Date, so that's why I need all other dates to be also in the format of SAS Date.
For the DateY I'm doing the following:
proc sql;
select DateY format ddyyyy10.
into :DateY
from DE.TRACK
where TABLE = "TRACK";
quit;
Is there a more correct way to do it?
SAS will allow you to create some pretty complicated date /datetime formats. But the meaning has to be clear. For example you have DDYYYY10. How would 31DEC2024 appear with that format? There are functions and formats related to JULIAN dates, which use the day of the year (3 digits to accomaded 365/366) plus the year (2 or 4 digits). But asking for what appears to be 2 digits for Day and 4 for year and then using 10 characters to display sounds likely to have other issues.
data _null_;
call symputx('yesterday', put(intnx('day', today(), -1), ddmmyy10.));
run;
%put &=yesterday;
data _null_;
call symputx('yesterday', put(intnx('day', today(), -1), worddate.));
run;
%put &=yesterday;
Koen
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.
Ready to level-up your skills? Choose your own adventure.