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

Hi,

i have this macro, it  works:

 

   %macro date_loop(start,end);
   %let start=%sysfunc(inputn(&start,DATETIME16.));
   %let end=%sysfunc(inputn(&end,DATETIME16.));
   %let dif=%sysfunc(intck(HOUR,&start,&end));
     %do i=0 %to &dif;
      %let DATA_INIZIO=%sysfunc(intnx(HOUR,&start,&i,b),DATETIME16.);
	  %let DATA_FINE=%sysfunc(intnx(HOUR,"&DATA_INIZIO"dt,1),DATETIME16.);
      %put &DATA_INIZIO;

	  	  	PROC SQL ; /* ACCODO */ 
			CREATE TABLE  LDS.TORARIO_VUOTO_p  AS 
			
			SELECT 
			KEYATM,
			"&DATA_INIZIO"dt FORMAT=DATETIME16. AS   DATA_INIZIO,
			"&DATA_FINE"dt  FORMAT=DATETIME16. AS   DATA_FINE,

			 datepart("&DATA_INIZIO"dt ) FORMAT=DDMMYY10. AS Date,
			HOUR("&DATA_INIZIO"dt )   FORMAT=BEST12. AS Time,
			WEEKDAY( datepart("&DATA_INIZIO"dt ) ) FORMAT=BEST12. AS Day

			from LDS.TORARIO_ANAG A
			 WHERE KEYATM   = '020081319902752'
			;
			quit;


     %end;
   %mend date_loop;

   %date_loop(01FEB19:00:00:00,28FEB19:23:59:59);

But i need to insert into macro two variables for this value fd = 01FEB19:00:00:00   ld=28FEB19:23:59:59, to determine automatically

first and last hour of month:

 

 

data _null_;
dt = '01FEB2019:00:00:00'dt; 
fd = intnx('dtmonth', dt, 0, 'B');
ld = intnx('dtmonth', dt, 0, 'E');

fd= put(fd,datetime.);
ld= put(Ld,datetime.);
run;

%put NOTE: &fd &ld &dt;

 

 

i have this error, can you tell me what the error is in the format? thank's :

 

  data _null_;
197      dt = '01FEB2019:00:00:00'dt;
198      fd = intnx('dtmonth', dt, 0, 'B');
199      ld  = intnx('dtmonth', dt, 0, 'E');
200
201      fd= put(fd,datetime.);
202      ld= put(Ld,datetime.);
203  run;

NOTE: Character values have been converted to numeric values at the places given by:
      (Line):(Column).
      201:9   202:9
NOTE: Invalid numeric data, '01FEB19:00:00:00' , at line 201 column 9.
NOTE: Invalid numeric data, '28FEB19:23:59:59' , at line 202 column 9.
dt=1864598400 fd=. ld=. _ERROR_=1 _N_=1
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds


204
205  %put NOTE: &fd &ld  &dt;
NOTE:            .            .    1861920000

 

 

1 ACCEPTED SOLUTION

Accepted Solutions
Tom
Super User Tom
Super User

It sounds like your question is just how to generate macro variables with strings that LOOK LIKE datatime values?

It is very easy to do.

First you need to start with a value that is a valid datetime values.

%let dt = '01FEB2019:00:00:00'dt; 

Then you can use INTNX() function.  Make sure to use a width on the format that is long enough that SAS will include 4 digits for the year. (Remember Y2K?)

%let fd=%sysfunc(intnx(dtmonth,&dt,0,b),datetime20);
%let ld=%sysfunc(intnx(dtmonth,&dt,0,e),datetime20);

Results:

251   %put &=dt;
DT='01FEB2019:00:00:00'dt
252   %put &=fd;
FD=01FEB2019:00:00:00
253   %put &=ld;
LD=28FEB2019:23:59:59

Notice how the new macro variables look different from the first one?

If you want to use those values as datetime literals in your code then make sure to add the quotes and dt suffix.

%let fd=%sysfunc(intnx(dtmonth,&dt,0,b),datetime20);
%let fd="&fd"dt;
%let ld=%sysfunc(intnx(dtmonth,&dt,0,e),datetime20);
%let ld="&ld"dt;

Results:

244   %put &=dt;
DT='01FEB2019:00:00:00'dt
245   %put &=fd;
FD="01FEB2019:00:00:00"dt
246   %put &=ld;
LD="28FEB2019:23:59:59"dt

 

View solution in original post

10 REPLIES 10
Ksharp
Super User

You override variables fd,ld .

 

data _null_;
dt = '01FEB2019:00:00:00'dt; 
fd = intnx('dtmonth', dt, 0, 'B');
ld = intnx('dtmonth', dt, 0, 'E');

new_fd= put(fd,datetime.);
new_ld= put(Ld,datetime.);
run;

 

 

Cello23
Quartz | Level 8

i tried but i have an error:

data _null_;
    fd = intnx('dtmonth', &dt, 0, 'B');
    ld  = intnx('dtmonth', &dt, 0, 'E');
 
	fd_new= put(fd,datetime.);
	ld_new= put(Ld,datetime.);
	put fd_new d  ld_new;
run;

%put NOTE: &fd_new;
 
 
 
   %macro date_loop(start,end);
   %let start=%sysfunc(inputn(&start,DATETIME16.));
   %let end=%sysfunc(inputn(&end,DATETIME16.));
   %let dif=%sysfunc(intck(HOUR,&start,&end));
     %do i=0 %to &dif;
      %let DATA_INIZIO=%sysfunc(intnx(HOUR,&start,&i,b),DATETIME16.);
	  %let DATA_FINE=%sysfunc(intnx(HOUR,"&DATA_INIZIO"dt,1),DATETIME16.);
      %put &DATA_INIZIO;

	  	  	PROC SQL ; /* ACCODO */ 
			CREATE TABLE  LDS.TORARIO_VUOTO_p  AS 
			
			SELECT 
			KEYATM,
			"&DATA_INIZIO"dt FORMAT=DATETIME16. AS   DATA_INIZIO,
			"&DATA_FINE"dt  FORMAT=DATETIME16. AS   DATA_FINE,

			 datepart("&DATA_INIZIO"dt ) FORMAT=DDMMYY10. AS Date,
			HOUR("&DATA_INIZIO"dt )   FORMAT=BEST12. AS Time,
			WEEKDAY( datepart("&DATA_INIZIO"dt ) ) FORMAT=BEST12. AS Day

			from LDS.TORARIO_ANAG A
			 WHERE KEYATM   = '020081319902752'
			;
			quit;


     %end;
   %mend date_loop;

   %date_loop(&fd_new,&ld_new);

 Log error:

276  data _null_;
277      fd = intnx('dtmonth', &dt, 0, 'B');
278      ld  = intnx('dtmonth', &dt, 0, 'E');
279
280      fd_new= put(fd,datetime.);
281      ld_new= put(Ld,datetime.);
282      put fd_new d  ld_new;
283  run;

NOTE: Variable d is uninitialized.
01JAN19:00:00:00 . 31JAN19:23:59:59
NOTE: DATA statement used (Total process time):
      real time           0.01 seconds
      cpu time            0.01 seconds


WARNING: Apparent symbolic reference FD_NEW not resolved.
284
285  %put NOTE: &fd_new;
NOTE: &fd_new
286
287
288
289     %macro date_loop(start,end);
290     %let start=%sysfunc(inputn(&start,DATETIME16.));
291     %let end=%sysfunc(inputn(&end,DATETIME16.));
292     %let dif=%sysfunc(intck(HOUR,&start,&end));
293       %do i=0 %to &dif;
294        %let DATA_INIZIO=%sysfunc(intnx(HOUR,&start,&i,b),DATETIME16.);
295        %let DATA_FINE=%sysfunc(intnx(HOUR,"&DATA_INIZIO"dt,1),DATETIME16.);
296        %put &DATA_INIZIO;
297
298              PROC SQL ; /* ACCODO */
299              CREATE TABLE  LDS.TORARIO_VUOTO_p  AS
300
301              SELECT
302              KEYATM,
303              "&DATA_INIZIO"dt FORMAT=DATETIME16. AS   DATA_INIZIO,
304              "&DATA_FINE"dt  FORMAT=DATETIME16. AS   DATA_FINE,
305
306               datepart("&DATA_INIZIO"dt ) FORMAT=DDMMYY10. AS Date,
307              HOUR("&DATA_INIZIO"dt )   FORMAT=BEST12. AS Time,
308              WEEKDAY( datepart("&DATA_INIZIO"dt ) ) FORMAT=BEST12. AS Day
309
310              from LDS.TORARIO_ANAG A
311               WHERE KEYATM   = '020081319902752'
312              ;
313              quit;
314
315
316       %end;
317     %mend date_loop;
318
319     %date_loop(&fd_new,&ld_new);
WARNING: Apparent symbolic reference FD_NEW not resolved.
WARNING: Apparent symbolic reference LD_NEW not resolved.
WARNING: Apparent symbolic reference FD_NEW not resolved.
WARNING: Argument 1 to function INPUTN referenced by the %SYSFUNC or %QSYSFUNC macro function is
         out of range.
NOTE: Mathematical operations could not be performed during %SYSFUNC function execution. The
      result of the operations have been set to a missing value.
WARNING: Apparent symbolic reference LD_NEW not resolved.
WARNING: Argument 1 to function INPUTN referenced by the %SYSFUNC or %QSYSFUNC macro function is
         out of range.
NOTE: Mathematical operations could not be performed during %SYSFUNC function execution. The
      result of the operations have been set to a missing value.
ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric
       operand is required. The condition was: &dif
ERROR: The %TO value of the %DO I loop is invalid.
ERROR: The macro DATE_LOOP will stop executing.

thank's

 

Tom
Super User Tom
Super User

You are trying to reference a macro variable you never created.

You can use CALL SYMPUTX() to create a macro variable in a data step.

Cello23
Quartz | Level 8

i tried:

 		data _null_;
		call symput('dt', '01JAN2019:00:00:00'dt );
		run;

  		data _null_;
		 call symput('FD', intnx('dtmonth', &dt, 0, 'B') );
		 call symput('LD', intnx('dtmonth', &dt, 0, 'E') );
  		run;

  		data _null_;
		 call symput('FD_new', put(datepart(&fd),datetime.) );
		 call symput('LD_new', put(datepart(&ld),datetime.) );
  		run;

i have this error:

336
337
338          data _null_;
339          call symput('dt', '01JAN2019:00:00:00'dt );
340          run;

NOTE: Numeric values have been converted to character values at the places given by:
      (Line):(Column).
      339:27
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds


341
342          data _null_;
343           call symput('FD', intnx('dtmonth', &dt, 0, 'B') );
344           call symput('LD', intnx('dtmonth', &dt, 0, 'E') );
345          run;

NOTE: Numeric values have been converted to character values at the places given by:
      (Line):(Column).
      343:28   344:28
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds


346
347          data _null_;
348           call symput('FD_new', put(datepart(&fd),datetime.) );
349           call symput('LD_new', put(datepart(&ld),datetime.) );
350          run;

NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds

thank's!!

Tom
Super User Tom
Super User

Why are you using the older call symput() function instead of the newer call symputx()?  Only use the older version if you need to have leading or trailing spaces written into the macro variable.

 

What are you going to use these macro variables to do?

If you are just going to use them to assign values or compare values there is no need to apply any format to them.

202   data _null_;
203     call symputx('today',date());
204     call symputx('now',datetime());
205   run;

NOTE: DATA statement used (Total process time):
      real time           0.09 seconds
      cpu time            0.01 seconds


206   %put &=today &=now;
TODAY=21628 NOW=1868695382.4
207
208   data _null_;
209     if date()=&today then put 'It is today.';
210     if abs(datetime()-&now) < 60*60 then put 'It is within an hour of now.';
211   run;

It is today.
It is within an hour of now.
NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds

If you do want to store the formatted value (a string instead of a number) into the macro variable then convert using the format. Make sure to use a format that is long enough to store the full four digits of the year.  But then if you want to use those values in your code you will need add quotes and suffix make valid date or datetime literal values.

212   data _null_;
213     call symputx('today',put(date(),date9.));
214     call symputx('now',put(datetime(),datetime20.));
215   run;

NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.01 seconds


216   %put &=today &=now;
TODAY=20MAR2019 NOW=20MAR2019:10:05:05
217
218   data _null_;
219     if date()="&today"d then put 'It is today.';
220     if abs(datetime()-"&now"dt) < 60*60 then put 'It is within an hour of now.';
221   run;

It is today.
It is within an hour of now.
NOTE: DATA statement used (Total process time):
      real time           0.04 seconds
      cpu time            0.01 seconds

 

Kurt_Bremser
Super User

These are not ERRORs, these are NOTEs that inform you about implicit type conversions.

By using call symputx() instead of call symput(), you can suppress those NOTEs:

data _null_;
call symputx('dt','01JAN2019:00:00:00'dt);
run;

data _null_;
call symputx('FD',intnx('dtmonth',&dt,0,'B'));
call symputx('LD',intnx('dtmonth',&dt,0,'E'));
run;

data _null_;
call symputx('FD_new',put(datepart(&fd),datetime.));
call symputx('LD_new',put(datepart(&ld),datetime.));
run;

%put fd_new=&fd_new.;
%put ld_new=&ld_new.;

Log:

27         data _null_;
28         call symputx('dt','01JAN2019:00:00:00'dt);
29         run;

NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds
      

30         
31         data _null_;
32         call symputx('FD',intnx('dtmonth',&dt,0,'B'));
33         call symputx('LD',intnx('dtmonth',&dt,0,'E'));
34         run;

NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds
      

35         
36         data _null_;
37         call symputx('FD_new',put(datepart(&fd),datetime.));
38         call symputx('LD_new',put(datepart(&ld),datetime.));
39         run;

NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds
      

2                                                          Das SAS System                            07:11 Wednesday, March 20, 2019

40         
41         %put fd_new=&fd_new.;
fd_new=01JAN60:05:59:10
42         %put ld_new=&ld_new.;
ld_new=01JAN60:05:59:40
Cello23
Quartz | Level 8

Using the modification you suggested, the result is not right,  fd_new = 01JAN60:05:59:10 and ld_new =01JAN60:05:59:4 :

 496
497 %put fd_new=&fd_new.;
fd_new=01JAN60:05:59:10
498 %put ld_new=&ld_new.;
ld_new=01JAN60:05:59:4

 

The result should be fd_new = 01JAN19:00:00:00   (begin of month) and ld_new =31JAN19:23:59:59 (end of month)

 

thank's

Kurt_Bremser
Super User

I mistakenly copied your wrong datepart() calls.

Simplify the code to

%let dt='01JAN2019:00:00:00'dt;

data _null_;
call symputx('FD',put(intnx('dtmonth',&dt,0,'B'),datetime19.));
call symputx('LD',put(intnx('dtmonth',&dt,0,'E'),datetime19.));
run;

%put fd=&fd.;
%put ld=&ld.;

Log:

27         %let dt='01JAN2019:00:00:00'dt;
28         
29         data _null_;
30         call symputx('FD',put(intnx('dtmonth',&dt,0,'B'),datetime19.));
31         call symputx('LD',put(intnx('dtmonth',&dt,0,'E'),datetime19.));
32         run;

NOTE: DATA statement used (Total process time):
      real time           0.00 seconds
      cpu time            0.00 seconds
      

33         
34         %put fd=&fd.;
fd=01JAN2019:00:00:00
35         %put ld=&ld.;
ld=31JAN2019:23:59:59
Tom
Super User Tom
Super User

It sounds like your question is just how to generate macro variables with strings that LOOK LIKE datatime values?

It is very easy to do.

First you need to start with a value that is a valid datetime values.

%let dt = '01FEB2019:00:00:00'dt; 

Then you can use INTNX() function.  Make sure to use a width on the format that is long enough that SAS will include 4 digits for the year. (Remember Y2K?)

%let fd=%sysfunc(intnx(dtmonth,&dt,0,b),datetime20);
%let ld=%sysfunc(intnx(dtmonth,&dt,0,e),datetime20);

Results:

251   %put &=dt;
DT='01FEB2019:00:00:00'dt
252   %put &=fd;
FD=01FEB2019:00:00:00
253   %put &=ld;
LD=28FEB2019:23:59:59

Notice how the new macro variables look different from the first one?

If you want to use those values as datetime literals in your code then make sure to add the quotes and dt suffix.

%let fd=%sysfunc(intnx(dtmonth,&dt,0,b),datetime20);
%let fd="&fd"dt;
%let ld=%sysfunc(intnx(dtmonth,&dt,0,e),datetime20);
%let ld="&ld"dt;

Results:

244   %put &=dt;
DT='01FEB2019:00:00:00'dt
245   %put &=fd;
FD="01FEB2019:00:00:00"dt
246   %put &=ld;
LD="28FEB2019:23:59:59"dt

 

Cello23
Quartz | Level 8

Tom and   , your answers will solve my problem, thank's so much!! 

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

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
  • 10 replies
  • 3000 views
  • 2 likes
  • 4 in conversation