BookmarkSubscribeRSS Feed
Ju_Fr
Calcite | Level 5

Hello everyone, 

I feel like my issue is a simple one yet I have been stuck on this for hours. I am trying to convert a SAS date variable (datetime20. format) into a string of characters YYYYMMDD inside a macro (code lines in bold). 

My macro calculates the number of months between my start and end date and then executes another macro (%request) at each incremented month.  I need to transform my start date (a SAS date) to a string YYYYMMDD so that the second macro will run. 

 

When I run my programme I get stuck at the first loop and I come across this note :  

NOTE : Macro variable CHAR_DAY resolves to inputn('01JUL2014'd,yymmddn8.). It doesn't look like it's converting my date to a string. 

Could anyone help? 

Many thanks, 

Juliette  

 

 

%macro hormono(start_dt=,end_dt=);

%let nbmonths=%eval(%sysfunc(intck(month,&start_dt.,&end_dt.)));

       %do i=0 %to &nbmonths;
       %if &i=0 %then %do;
       %let char_day=inputn(&start_dt.,yymmddn8.);
                %request(database, &char_day.);
       %end;
       %else %do;
       %let char_day2=inputn(%sysfunc(intnx(month,&start_dt,&i,s)),yymmddn8.);
               %request(temp, &char_day2.);
               proc sql;
               insert into database
               select * from temp;
              quit;
      %end;
%end;

%mend hormono;

5 REPLIES 5
SASKiwi
PROC Star

Perhaps something like this?

%let start_dt = %sysfunc(datetime(), datetime20.);
%put start_dt = &start_dt;
%let char_day = %sysfunc(datepart("&start_dt"dt), yymmddn8.);
%put char_day = &charday;
Reeza
Super User
Can you show how the macro is being called?
And what you want to pass to REQUEST?

You're nesting the %SYSFUNC() and INPUTN() incorrectly but not 100% sure I understand what is the input. INPUT assumes that your date comes in as YYMMDD (2014-07-01) but you said it's a datetime? If so, the datetime also requires to be converted to a date type variable.
Tom
Super User Tom
Super User

You can use INTCK() to count the number of months and INTNX() to generate the months.

But if you have two DATETIME values (which are NOT dates) you need to use the DTMONTH interval and not the MONTH interval.

%macro hormono(start_datetime,end_datetime);
%local offset  ;
%do offset = 0 %to %sysfunc(intck(dtmonth,&start_datetime,&end_datetime));
  %request(temp, %sysfunc(datepart(%sysfunc(intnx(dtmonth,&start_datetime,&offset))),yymmddn8.))
  proc append base=database data=temp;
  run;
%end;
%mend hormono;

%hormono('01JAN2020:00:00'dt,'01DEC2020:00:00'dt)
ballardw
Super User

First issue is this: "convert a SAS date variable (datetime20. format) "

SAS Date variables are measured in DAYS, Datetime values are measured in seconds. Since the units are different you have to pay attention to parameters used. If apply a datetime20 format to a date value you typically see results in the early 1960's, the other way around, applying a date format to a datetime you typically get out of range results for recent dates.

 

In the INTNX and INTCK functions if the value is a DATETIME then you prefix intervals that involve the date portion with DT: dtday, dtmonth, dtyear and such. The RESULT is still a date time with INTNX. To get the DATE part from a DATETIME value you use the DATEPART function. INPUTING the result of INTNX is just wrong, it is a date, time or datetime value and one that if an informat actually returns a result will almost never be the date, time or datetime you think it should.

Example to consider:

data example;
   x="01Jan1960:12:00:00"dt;
   y="01MAR1960:12:00:00"dt;
   format x y datetime20.;
   z1= intck('month',x,y);
   z2= intck('dtmonth',x,y);
   put z1= z2= ;
run;

These datetime values are pretty obviously 2 months apart. If you use MONTH for the interval the result, as in Z1 above, is 170320. Z2=2.

 

INPUTN is a function, just like INTCK. So you need to use %sysfunc (inputn(<stuff>) )

 

Your partial LOG strongly implies that you passed a character value and Input with something that looks like '01JUL2014'd is just wrong. That is a date literal which SAS treats as date. Trying to input with a YYMMDDN just compounds the issue because '01JUL2014'd starts with '01, not a year, the month is the 3-letter abbreviation not the 2 digits and the ending year is just not going to work with that informat.

With that said, you need to show some actual values used as your parameters Start_dt and End_dt and tell use what the expected result is for those.

Kurt_Bremser
Super User

Here you assume that &start_dt is either a raw SAS date value, or a valid date literal:

%eval(%sysfunc(intck(month,&start_dt.,&end_dt.)))

But here you assume it is a string containing a date in YYYYMMDD notation:

%let char_day=inputn(&start_dt.,yymmddn8.)

This function call would not work anyway, for two reasons: no %SYSFUNC wrapper, and there is no YYMMDDN informat.

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!

How to Concatenate Values

Learn how use the CAT functions in SAS to join values from multiple variables into a single value.

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
  • 5 replies
  • 1168 views
  • 1 like
  • 6 in conversation