BookmarkSubscribeRSS Feed
Mick_lb
Calcite | Level 5

Hello everyone, 

 

From a date, I want to take the last day of the previous month. And after that, display the month and the year (of the previous month).

The problem is, my code is working for every month except January.

 

%let date="01JAN2017:00:00:00"dt;
%put ===> &date.;

data _null_;
last_day = day(intnx('month', datepart(&date.), -1, "end"));
CALL SYMPUT("last_day",PUT(last_day,DATE9.));
/*To display the month*/
p_month=MDY(month(datepart(&date.))-1, last_day, year(datepart(&date.))); /*Error here*/
CALL SYMPUT("p_month",PUT(p_month,FRADFMN.));
/*To display the year*/
p_year=MDY(month(datepart(&date.))-1, last_day, year(datepart(&date.))); /*Error here*/
CALL SYMPUT("p_year",PUT(p_year,YEAR4.));
run;
%put ===> &last_day.;
%put ===> &p_month.;
%put ===> &p_year.;

For January, I got the following error :

NOTE: Invalid argument for MDY function (0,31,2017) at line 31 column 9.

NOTE: Invalid argument for MDY function (0,31,2017) at line 34 column 8.

last_day=31 p_month=. p_year=. _ERROR_=1 _N_=1

NOTE: Mathematical operations could not be performed at the following places. The results of the operations have been set to missing values.

How to tell SAS not to take month = 0 when it's January ?

 

Thank you in advance for your help !

 

Best regards,

3 REPLIES 3
Kurt_Bremser
Super User

Overcomplicating things by a mile.

data _null_;
last_date = intnx('month', datepart(&date.), -1, "end");
CALL SYMPUT("last_day",PUT(day(last_date),2.));
/*To display the month*/
CALL SYMPUT("p_month",PUT(month(last_date),2.);
/*To display the year*/
CALL SYMPUT("p_year",PUT(year(last_date),4.));
run;
ed_sas_member
Meteorite | Level 14

Hi @Mick_lb 

You need to be very careful with dates in macro variables.

It should not be formatted to be used for further calculation

Typically, 01JAN2017 (which is human-readable) is stored as the numeric value 20820 by SAS (= number of days since 01JAN1960)

 

Best,

 

%let date=01JAN2017:00:00:00;
%put ===> &date;

%let date_2=%sysfunc(datepart(%sysfunc(inputn(&date,datetime18))));

%let last_day=%sysfunc(day(%sysfunc(intnx(month,&date_2,-1,end))));
%let p_month=%sysfunc(month(%sysfunc(intnx(month,&date_2,-1,end))));
%let p_year=%sysfunc(year(%sysfunc(intnx(month,&date_2,-1,end))));

%put ===> &last_day.;
%put ===> &p_month.;
%put ===> &p_year.;

 

Reeza
Super User

INTNX() is used to move the date back one month, you can not use base math here because you cycle from 1 to 12 with month. You can use MOD() if you want to use math type functions, but using INTNX() appropriately is a better approach. 

 


@Mick_lb wrote:

Hello everyone, 

 

From a date, I want to take the last day of the previous month. And after that, display the month and the year (of the previous month).

The problem is, my code is working for every month except January.

 

%let date="01JAN2017:00:00:00"dt;
%put ===> &date.;

data _null_;
last_day = day(intnx('month', datepart(&date.), -1, "end"));
CALL SYMPUT("last_day",PUT(last_day,DATE9.));
/*To display the month*/
p_month=MDY(month(datepart(&date.))-1, last_day, year(datepart(&date.))); /*Error here*/
CALL SYMPUT("p_month",PUT(p_month,FRADFMN.));
/*To display the year*/
p_year=MDY(month(datepart(&date.))-1, last_day, year(datepart(&date.))); /*Error here*/
CALL SYMPUT("p_year",PUT(p_year,YEAR4.));
run;
%put ===> &last_day.;
%put ===> &p_month.;
%put ===> &p_year.;

For January, I got the following error :

NOTE: Invalid argument for MDY function (0,31,2017) at line 31 column 9.

NOTE: Invalid argument for MDY function (0,31,2017) at line 34 column 8.

last_day=31 p_month=. p_year=. _ERROR_=1 _N_=1

NOTE: Mathematical operations could not be performed at the following places. The results of the operations have been set to missing values.

How to tell SAS not to take month = 0 when it's January ?

 

Thank you in advance for your help !

 

Best regards,


 

sas-innovate-2024.png

Available on demand!

Missed SAS Innovate Las Vegas? Watch all the action for free! View the keynotes, general sessions and 22 breakouts on demand.

 

Register now!

Mastering the WHERE Clause in PROC SQL

SAS' Charu Shankar shares her PROC SQL expertise by showing you how to master the WHERE clause using real winter weather data.

Find more tutorials on the SAS Users YouTube channel.

Discussion stats
  • 3 replies
  • 873 views
  • 0 likes
  • 4 in conversation