Home > Enterprise >  SAS set the 'middle' parameter of intnx to always set to the 15th
SAS set the 'middle' parameter of intnx to always set to the 15th

Time:01-18

I have the following SAS codes:

DATA _NULL_;
today = today();
    if day(today) ge 1 and day(today) le 15 then do;
        date2=put(intnx('month',today,-1,'m'), date11.);
        date1=put(intnx('month',today,-1,'E'), date11.);
    end;
    if day(today) > 15 then do;
        date2=put(intnx('month',today,0,'B'), date11.);
        date1=put(intnx('month',today,0,'m'), date11.); 
    end;
    call symput('dt',date1);
    call symput('dt2',date2);
RUN;

The code above says if the date part of today's date is less than or equal to 15, set date2 to the middle of last month and date1 be set to the last/end of last month. otherwise, set date2 to the beginning of the current month and date1 to the middle of the current month.

I like how SAS has the 'm' or 'middle' to get the middle date of the month. It works great with months that have 30 days and the middle will fall on the 15th. But on months with 31 days, it will always fall on the 16th, special case with February. What I would like is to always make the middle be on the 15th.

I tried adding '-1' to every line to check if it will give me what I need, but it returns a blank date when I call the variable. It returns a dot for a not working date call with -1.

one of them is %put &rpt_dt. &rpt_dt2.; . 01-JAN-2023

Since January has 31 days and if I put the -1 as such:

date1=put(intnx('month',today,0,'m')-1, date11.); 

I will get the desired Jan15th, but it will not be dynamic. If the same code with -1 will be run next month, the code will always subtract 1 and it will fall a day before the middle, same with months that have 30 days.

CodePudding user response:

You can use mdy() to force it to be the 15th for every month. In your first case, set the date to the previous month first, then force it to be the 15th with mdy(). See the changed code below.

data _null_;

    /* Add a shift and alignment depending on the day of the month */
    if(day(today()) LE 15) then do;
        shift = -1;
        align = 'E';
    end;
        else do;
            shift = 0;
            align = 'B';
        end;

    /* Calculate a temporary date and shift it depending on previous conditions */
    date = intnx('month', today(), shift);
    
    /* Re-align the temporary date and save it to a macro variable */
    call symputx('dt',  put(intnx('month', date, 0, align), date11.) );
    call symputx('dt2', put(mdy(month(date), 15, year(date)), date11.) );
run;

CodePudding user response:

If you literally want it to be the 15th exactly, then why not do this?

date1=put(intnx('month',today,0,'b') 14, date11.); 

Seems straightforward to me...

  • Related