I am apparently not seeing something simple in this code. The below code returns a testdate of 1/1/60, but the log somehow is recognizing the macro variable correctly as 9/30/24. How do i get that macro variable date into my dataset? I think i've done this a million times but today it doesn't seem to be working for me.
%let lastday = %sysfunc(intnx(month,%sysfunc(today()),-1,e),mmddyy10.);
data test;
set have;
testdate = &lastday;
format testdate mmddyy10.;
run;
log:
28 %let lastday = %sysfunc(intnx(month,%sysfunc(today()),-1,e),mmddyy10.);
29
30 data test;
31 set have;
32 testdate = &lastday;
SYMBOLGEN: Macro variable LASTDAY resolves to 09/30/2024
33 format testdate mmddyy10.;
34 run;
Look carefully at the SAS code you asked the macro processor to generate for you.
If the macro variable LASTDAY has the string 09/30/2024 and you use it like this:
testdate = &lastday;
Then you asked SAS to run this line of code:
testdate = 09/30/2024;
Since 9 divided by 30 divided by 2024 is going to be between 0 and 1 the MMDDYY10. format will display that as 01/01/1960 since the number 0 is used by SAS to represent the first day of 1960.
Why did you format the value at all? If you just use
%let lastday=%sysfunc(intnx(month,%sysfunc(today()),-1,e));
Then you should get LASTDAY set to the string 23649 which the MMDDYY10. format will display as 09/30/2024.
338 %let lastday=%sysfunc(intnx(month,%sysfunc(today()),-1,e)); 339 340 data test; 341 x=&lastday; 342 put x= x mmddyy10.; 343 run; x=23649 09/30/2024
Look carefully at the SAS code you asked the macro processor to generate for you.
If the macro variable LASTDAY has the string 09/30/2024 and you use it like this:
testdate = &lastday;
Then you asked SAS to run this line of code:
testdate = 09/30/2024;
Since 9 divided by 30 divided by 2024 is going to be between 0 and 1 the MMDDYY10. format will display that as 01/01/1960 since the number 0 is used by SAS to represent the first day of 1960.
Why did you format the value at all? If you just use
%let lastday=%sysfunc(intnx(month,%sysfunc(today()),-1,e));
Then you should get LASTDAY set to the string 23649 which the MMDDYY10. format will display as 09/30/2024.
338 %let lastday=%sysfunc(intnx(month,%sysfunc(today()),-1,e)); 339 340 data test; 341 x=&lastday; 342 put x= x mmddyy10.; 343 run; x=23649 09/30/2024
Do the arithmetic. 9 divided by 30 is 0.3. Divide that by 2024. The result is 0.0001482213 approximately.
The Date Formats use number of days from 1 Jan 1960. So any value between 0 and is 1 Jan 1960, 1 is 2 Jan, 2 is 3 jan and so on.
The code you created resolves the macro variable exactly as text:
data test; testdate = 09/30/2024; format testdate mmddyy10.; run;
You told it to divide some values.
The only way to write a LITERAL DATE is to use something that looks like the Date9 or similar formats and to be treated as date must be in quotes and followed by a 😧 '30SEP2024'D;
However if you did not format the date created by the macro:
%let lastday = %sysfunc(intnx(month,%sysfunc(today()),-1,e)); data test; testdate = &lastday.; format testdate mmddyy10.; run;
Then Lastday will have the correct numeric value of number of days and the format then makes sense to display that.
There are so many ways to display dates, times and datetime values, just check on the SAS supplied formats, that they picked one for coding literal values. The '09SEP2024'd version has the property of being relatively legible across cultures where dd/mm or mm/dd can be confused quite easily for about a third of a year. Similar if you use time literal values: "15:20:16"T note the default 24 hour clodk, or datetime values "09SEP2024:15:20:16"dt
Don’t miss the livestream kicking off May 7. It’s free. It’s easy. And it’s the best seat in the house.
Join us virtually with our complimentary SAS Innovate Digital Pass. Watch live or on-demand in multiple languages, with translations available to help you get the most out of every session.
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.