DATA Step, Macro, Functions and more

Macro programming for dates

Reply
Contributor
Posts: 60

Macro programming for dates

Hello,

 

I'm looking to create macros in SAS that will allow me to quick reference dates in my code.

 

I would like to have the following...

 

Today 

Today Last year

Today 3Mths ago

Today 6Mths ago

Today 9Mths ago

First Day of Prev Month

Last Day of Prev Month

 

 

Thanks,

Cam

 

Super User
Super User
Posts: 7,988

Re: Macro programming for dates

Posted in reply to CamRutherford

Why would you need macro when there is perfectly good functions for this:

Today                              = today()

Today Last year                = intnx('year',today(),-1)

Today 3Mths ago              = intnx('month',today(),-3)

Today 6Mths ago              ... same

Today 9Mths ago              ... same

First Day of Prev Month    = intnx('day',intnx(month,today(),-1),1,'b')

Last Day of Prev Month    = intnx('day',intnx(month,today(),-1),1,'e')

 

There is never a need to use macro.

Contributor
Posts: 60

Re: Macro programming for dates

Hi,

 

I'd want a macro because I reference these dates a lot and would make my code more aesthetically pleasing.

 

Thanks,

Cam

Super User
Posts: 7,854

Re: Macro programming for dates

Posted in reply to CamRutherford

CamRutherford wrote:

Hi,

 

I'd want a macro because I reference these dates a lot and would make my code more aesthetically pleasing.

 

Thanks,

Cam


If you include my code in your autoexec, no macro is needed. The macro variables will be created in the global symbol table.

"autoexec" could be:

- the autoexec_usermods.sas file in your configuration

- any autoexec.sas file used by a sas start script/command (ie sasbatch)

- in the "custom code" to be sent when a server connection is opened in Enterprise Guide

- in a "autoexec" process flow in your EG projects

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Contributor
Posts: 60

Re: Macro programming for dates

Posted in reply to KurtBremser
How would I reference each date though?
Super User
Posts: 7,854

Re: Macro programming for dates

Posted in reply to CamRutherford

call symput creates macro variables. Use the string supplied to the call routine as the first parameter as a macro variable reference, eg &today for todays's date. Note that it is the raw SAS date value (number of days from 01jan1960), hard to read for humans, but very easy to use in comparisons etc.

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Super User
Posts: 11,343

Re: Macro programming for dates

Posted in reply to CamRutherford

CamRutherford wrote:
How would I reference each date though?

I do something along these lines with a call in my autoexec to create a macro variable with a specific format that I use in title statements. The varible created is named prepdate. When I want to use it:

title2 "Prepared on: &prepdate";

 

You don't mention HOW you intend to use any of these variables. Do you want TEXT that is human readable or the Values that are used in comparisons (or possibly both which would work best with 2 variables, one for text and one for value).

Super User
Super User
Posts: 7,988

Re: Macro programming for dates

Posted in reply to CamRutherford

You may believe that macro is more aesthetically pleasing, I would just call it obfuscation.  SAS Programmers should all know or be able to look up the methodology of the various functions within Base SAS - this being the programming language.  They would not however know all about your particular mass of %&'s.  As @KurtBremser has stated you can use the code in a datastep to generate the required macro parameters, but do bear in mind these will be character, and you will always have to convert each time you want to use them further.  For instance, if you wanted yesterday, you would need:

intnx('day',input("&my_today_value",datetime.),-1);

Compare this to simple base SAS:

intnx('day',today(),-1);

Now add up every time you need to do that and you will see the number of processing/characters needed would in many cases exceed the benefit of storing some add-hoc dates.

Contributor
Posts: 60

Re: Macro programming for dates

So can I not create %let satatements for each date I will want to use?

Super User
Posts: 7,854

Re: Macro programming for dates

[ Edited ]
Posted in reply to CamRutherford

CamRutherford wrote:

So can I not create %let satatements for each date I will want to use?


Of course you can. But look at this:

%let lst_year=%sysfunc(intnx(year,%sysfunc(today()),-1,same),best.);

vs

data _null_;
date = intnx('year',today(),-1,'same');
call symput('lst_year',put(date,best.));
run;

and tell me which is easier to decipher.

 

PS I forgot to mention that both examples create identical macro variables.

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Contributor
Posts: 60

Re: Macro programming for dates

Posted in reply to KurtBremser
DO YOU MEAN...

%let lst_year=%sysfunc(intnx(month,%sysfunc(today()),-1,same)),best.));
Super User
Posts: 7,854

Re: Macro programming for dates

Posted in reply to CamRutherford

CamRutherford wrote:
DO YOU MEAN...

%let lst_year=%sysfunc(intnx(month,%sysfunc(today()),-1,same)),best.));

Yep. Changed my post. My maxim is that if there is more than one %sysfunc in a statement, I switch to a data step to get rid of the %sysfuncs.

This also makes your code easier to maintain, as more complex logic doesn't become as unwieldy in a data step as it does in a macro %let.

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Super User
Posts: 7,854

Re: Macro programming for dates

@RW9 keep in mind that I deliberately use the best. format for my "date" macro variables, so the raw values can be directly used in comparisons and calculations.

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Super User
Posts: 7,854

Re: Macro programming for dates

Posted in reply to CamRutherford
data _null_;
date = today();
call symput('today',put(date,best.));
date = intnx('year',today(),-1,'same');
call symput('today_lst',put(date,best.));
date = intnx('month',today(),-3,'same');
call symput('today_3m',put(date,best.));
date = intnx('month',today(),-6,'same');
call symput('today_6m',put(date,best.));
date = intnx('month',today(),-9,'same');
call symput('today_9m',put(date,best.));
date = intnx('month',today(),-1,'begin');
call symput('lst_month_1st',put(date,best.));
date = intnx('month',today(),-1,'end');
call symput('lst_month_lst',put(date,best.));
run;

Put that into an include file or into a macro of your choice.

(In case you put it into a macro, use call symputx with 'g')

---------------------------------------------------------------------------------------------
Maxims of Maximally Efficient SAS Programmers
Trusted Advisor
Posts: 1,584

Re: Macro programming for dates

[ Edited ]
Posted in reply to CamRutherford

data _NULL_;

  /*=== calculate dates ===*/

       dt = today();

       dt_3y = intnx('year',dt,-3,'same');

       dt_3m = intnx('month',dt,-3,'same');

       dt_6m = intnx('month',dt,-6,'same');

       dt_9m = intnx('month',dt,-9,'same');

       dt_fpm =  intnx('month',dt,-1,'beginning');

       dt_lpm =  intnx('month',dt,-1,'end');     /* or = toady() - day(today());  */

 

/*=== assign dates to macro variables ===*/

      call symput('toady',left(dt));

      call symput('dt_3y',left(dt_3y));

      ......     /* choose your macro variable names and assign the dates calculated */

run;

Ask a Question
Discussion stats
  • 15 replies
  • 164 views
  • 0 likes
  • 5 in conversation