SAS does it all very nicely for you, with just a couple of additions, assuming I've understood you correctly. For a start, it makes things much easier if you store your date value as "days since 1 Jan 1960", or 20755 in this case. The easiest way to do this is to use the %sysevalf function: %let rundate = %sysevalf("28oct2016"d); /* which requires you to reformat your date, of course */ Alternatively: %let rundate = %sysfunc(inputn(161028, yymmdd6.)); Now, the intnx function is your friend. This will return the beginning, middle or end of a period ('month' in this case, obviously). Couple that with some formats and you're away. %let startofmonth = %sysfunc(intnx(month, &rundate, 0, b), date9.);
%let endofmonth = %sysfunc(intnx(month, &rundate, 0, e), date9.);
%let drundate = %sysfunc(putn(&rundate, monyy5.));
%put &startofmonth &endofmonth &drundate; This displays: 01OCT2016 31OCT2016 OCT16 Note that this will return 1OCT2016 etc. To convert that in macro code is a little ugly, but will be reliable: %let endofmonth = %substr(&endofmonth, 1, 3)%lowcase(%substr(&endofmonth, 4, 2))%substr(&endofmonth, 6, 4); If you want to see 1 October 2016 instead (which doesn't require the substringing): %let startofmonth = %sysfunc(intnx(month, &rundate, 0, b), worddatx.); Your other option, to return the year and month: %put %sysfunc(putn(&rundate, yymmdd4.)); 1610
... View more