BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
KasDunphy
Calcite | Level 5

Our health care company counts membership based on the 15th of the month.  Currently, INTNX will return dates as of the middle of the month using the 'm' alignment argument.  But this returns 15 or 16 depending on the month.  I'd like to be able to specify the 15th (or even any day of the month) in the alignment argument.

Currently, we have to jump through a few hoops to get the job done.

%let ds_cur_d = today();

%let _15TH_DT  = %sysfunc(mdy(%sysfunc(month(&ds_cur_d)), 15, %sysfunc(year(&ds_cur_d))), mmddyyd10.);

Is there an easier way to do this?

1 ACCEPTED SOLUTION

Accepted Solutions
Reeza
Super User

You could create your own function using proc fcmp.

proc fcmp outlib=sasuser.functions.sample;

   function month15(start_date);

            n=intnx('month', start_date, 0, 'b')+14;     

         return (n);

   endsub;

run;quit;

options cmplib=(sasuser.functions);

%let ds_cur_d = %sysfunc(today());

%put &ds_cur_d;

%let _15TH_DT  = %sysfunc(month15(&ds_cur_d), mmddyyd10.);

%put &_15TH_DT;

View solution in original post

10 REPLIES 10
ballardw
Super User

How are you using the _15th_dt variable?

From the online help:

date4=intnx('month','01jan95'd,1,'sameday');

put date4 / date4 date7.;

So if you start with a 15th of the month, sameday goes to the 15th.

Reeza
Super User

You could create your own function using proc fcmp.

proc fcmp outlib=sasuser.functions.sample;

   function month15(start_date);

            n=intnx('month', start_date, 0, 'b')+14;     

         return (n);

   endsub;

run;quit;

options cmplib=(sasuser.functions);

%let ds_cur_d = %sysfunc(today());

%put &ds_cur_d;

%let _15TH_DT  = %sysfunc(month15(&ds_cur_d), mmddyyd10.);

%put &_15TH_DT;

Astounding
PROC Star

Good approach, and it can be done, but it's a little more complex than that.  If the start_date is the 1st day of the month, for example, the function has to return the 15th day of the prior month (not the 15th day of the current month).  A tweak to the third parameter of INTNX might do the trick.  Instead of 0:

0 - (day(start_date) < 15)

Haikuo
Onyx | Level 15

Wondering why 'month.15' not working while the shift index seems to work on 'year' or 'week'.

Reeza
Super User

I think it would be day15 wouldn't it?

How do you know that the first resolves to the 15 of the previous month? You can probably extend the function above to take the exact same parameters as intnx but a custom one as well that would do 15, based on the question, didn't see the need to do that.

Haikuo
Onyx | Level 15

, day15 would be 15-day intervals starting on Sunday? While I meant (also OP?) is the 15th day of every month?

Reeza
Super User

True...I'm not too familiar with the Interval custom options, personally I would just set it to beginning and add 15 Smiley Happy

Astounding
PROC Star

Reeza,

That's my interpretation of the problem ... if you count as of the 15th of the month to me that means that your time periods run from the 15th of the previous month to the the 15th of the current month (one of them gets included, and one of them gets included).

Your solution matches the original posted logic.  It's just that to me, if you are using the 25th day of one month or the 5th day of the next month, you should be getting the same starting date.  Perhaps that's not what the poster intended however ...

KasDunphy
Calcite | Level 5

Thanks everyone for your feedback.  Because our team uses _15TH_DT a lot , it makes sense to create a macro and share it.  Thanks Reeza.

Tom
Super User Tom
Super User

I am not sure what your exact requirements are but it should work if you subtract 15 and then use INTNX to find the beginning of the right month and then add back 14 days to get to the 15th.

data xx ;

do day = '01JAN2014'd to '16FEB2014'd ;

   start = intnx('month',day-15,0)+14;

   end = intnx('month',day-15,1)+14;

   inside = (start < day <= end);

   output;

end;

format day start end yymmdd10.;

run;


You could make the value 15 into a macro variable or the parameter to a macro.

%macro intnx_day_of_month(date,day,month);

intnx('month',&date - &day,&month)+&day-1

%mend;

data yy ;

do day = '01JAN2014'd to '16FEB2014'd ;

   start = %intnx_day_of_month(day,15,0);

   end = %intnx_day_of_month(day,15,1);

   inside = (start < day <= end);

   output;

end;

format day start end yymmdd10.;

run;

proc compare data=xx compare=yy;

run;

data

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

What is Bayesian Analysis?

Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.

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
  • 10 replies
  • 2274 views
  • 0 likes
  • 6 in conversation