turn on suggestions

Auto-suggest helps you quickly narrow down your search results by suggesting possible matches as you type.

Showing results for

Find a Community

- Home
- /
- SAS Programming
- /
- ODS and Base Reporting
- /
- Date and time variables in SAS macro behaviour. Da...

Topic Options

- Subscribe to RSS Feed
- Mark Topic as New
- Mark Topic as Read
- Float this Topic for Current User
- Bookmark
- Subscribe
- Printer Friendly Page

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

11-27-2015 03:47 AM

Hi

This is my first post in this community so I hope I'm in the right group.

Enterprise Guide 6.1 program on SAS 9.4

Im struggeling to understand what is the difference between the following two code sections and why time gives an error:

%Let TheDate= %Sysevalf('16NOV2015'd);

%Let ThisDay = TODAY();

%Put TheDate is &Dato and ThisDay is &Thisday and the diff is %EvAL(%EVAL(&TheDate) - %SYSFUNC(&ThisDay));

LOG: TheDate is 20408 and ThisDay is TODAY() and the diff is -11

%Let TheTime = %Sysevalf('23:49:02't);

%Let ThisTime = Time();

%Put TheTime is &TheTime and ThisTime is &ThisTime and the diff is %EVAL(%EVAL(&TheTime) - %sysfunc(&ThisTime))

LOG: ERROR: A character operand was found in the %EVAL function or %IF condition where a numeric operand is required. The condition was: 85742 - 35133.7005119323

TheTime is 85742 and ThisTime is Time() and the diff is

Thank you

Accepted Solutions

Solution

11-30-2015
06:44 AM

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

11-30-2015 06:44 AM

Thank you very much for helping me understand this issue.

It was the floating point returned by %sysfunc(&ThisTime) that confused me. It could not be resolved by the %eval since this only handles integers.

%Let TheDate= %Sysevalf('29NOV2015'd);

%Let ThisDay = TODAY();

%Put TheDate is &TheDate and ThisDay is &ThisDay and the diff is %EvAL((&TheDate) - %SYSFUNC(&ThisDay));

%Let TheTime = %Sysevalf('23:49:02't);

%Let ThisTime = Time();

%Put TheTime is &TheTime and ThisTime is &ThisTime or %SYSFUNC(&ThisTime) and the diff is %SYSEVALF(%SYSEVALF(&TheTime) - %sysfunc(&ThisTime));

Thank you.

All Replies

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

11-27-2015 04:51 AM

I would presume your problem is this, the today() part in ThisDay, which you are assuming to be a function, is actually just text, therefore when you use that macro variable the today() is just plain text and the today function doesn't get shown.

To be honest though, in this scenario, and its something I always say, why are you trying to do this in macro language? Simply put macro language is a method for generating text sent to the compiler. It's really not built to handle data processing. If you have to do it like this, then something like:

%Let TheDate=16NOV2015; data _null_; call symput('ThisDay',put(today(),date9.)); call symput('Result',put("&TheDate."d - today(),date9.)); run; %put TheDate is &TheDate, and ThisDay is &ThisDay. and the diff is &Result.;

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

11-27-2015 05:00 AM

First of all, welcome to the community!

There's a minor inconsistency in the code you have provided: "&Dato" must read "&TheDate" (case insensitive, though). Otherwise, SAS would have complained about the non-existent macro variable Dato.

Thanks to the application of %SYSEVALF in the definition of TheDate, this macro variable TheDate contains the value 20408. Hence, the inner "%EVAL" in your %PUT statement is redundant. (There is no need to "evaluate" the pure number again.)

The data step function call TODAY() is stored as text in macro variable ThisDay, as you see in the result of the %PUT statement and it is executed only when %SYSFUNC is applied. The result is the current SAS date value, an integer, today (on 27 Nov 2015) 20419. The outer "%EVAL" performs the calculation of 20408 minus 20419 equals -11.

Similar situation with time, but the difference is that the data step function TIME() in general returns the current time including fractions of a second, i.e. not an integer, but a floating-point number. While &TheTime contains the integer value 85742 (=number of seconds from 00:00:00 to 23:49:02), %sysfunc(&ThisTime) results in a floating-point number. The %EVAL function, however, can only evaluate *integer* arithmetic or logical expressions, hence the error when trying to calculate the time difference.

Just replace the outer "%EVAL" by "%SYSEVALF" (which is capable of floating-point arithmetic) and you will get the intended result. (Again, the inner "%EVAL" is redundant.)

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

11-27-2015 09:29 AM

Hi mate, welcome.

I've made a little change in your code and it worked as you said in the Log: TheDate is 20408 and ThisDay is TODAY() and the diff is -11

```
%Let TheDate= %sysfunc(datepart('16NOV2015:00:00:00'dt),best12.);
%Let ThisDay = %sysfunc(TODAY(),date9.);
%Put TheDate is &Dato and ThisDay is &Thisday and the diff is
%eval(%eval(%sysfunc(today(),best12.)) - %eval(&TheDate));
```

Hope this helps

Solution

11-30-2015
06:44 AM

- Mark as New
- Bookmark
- Subscribe
- Subscribe to RSS Feed
- Highlight
- Email to a Friend
- Report Inappropriate Content

11-30-2015 06:44 AM

Thank you very much for helping me understand this issue.

It was the floating point returned by %sysfunc(&ThisTime) that confused me. It could not be resolved by the %eval since this only handles integers.

%Let TheDate= %Sysevalf('29NOV2015'd);

%Let ThisDay = TODAY();

%Put TheDate is &TheDate and ThisDay is &ThisDay and the diff is %EvAL((&TheDate) - %SYSFUNC(&ThisDay));

%Let TheTime = %Sysevalf('23:49:02't);

%Let ThisTime = Time();

%Put TheTime is &TheTime and ThisTime is &ThisTime or %SYSFUNC(&ThisTime) and the diff is %SYSEVALF(%SYSEVALF(&TheTime) - %sysfunc(&ThisTime));

Thank you.