BookmarkSubscribeRSS Feed
apple
Calcite | Level 5

Hi,

 

I got the below code from someone else. It is supposed to account for leap year. So during a

 

1) leap year: 183<=A<366

2) non-leap year: 183<= A<365

 

 

%LET Year=

183<= A < 365+(4*INT(&Year/4)=&Year)

 

Can someone explain to me what this does -- (4*INT(&Year/4)=&Year)?

 

As far as I know  INT truncates a number to its integer.

 

Thank you

6 REPLIES 6
PaigeMiller
Diamond | Level 26

Instead of writing code (or using somebody else's code) to determine time intervals, you use the built-in SAS functions, which already account for leap years and for un-equal number of days in a month, and all other quirks of the modern calendar.

 

The functions are INTNX and INTCK, look them up, use them.

--
Paige Miller
kannand
Lapis Lazuli | Level 10

Here is a simple check that might be easy to understand.  Good luck to you...!!!

 

Data check_year;
     do year_value = 2000 to  2016;
        length leap $3;
        leap='no';
        If mod(year_value,4)=0 then leap='YES'; 
        If mod(year_value,100)=0 and 
            mod(year_value,400) ne 0 
        then leap='NO'; 
        output;
     end;
Run;
proc print noobs; var year_value leap;
run;

Here is the result of the code for your reference: 

 


year_value	leap
2000	YES
2001	no
2002	no
2003	no
2004	YES
2005	no
2006	no
2007	no
2008	YES
2009	no
2010	no
2011	no
2012	YES
2013	no
2014	no
2015	no
2016	YES

 

Here is some more literature from where I got the calc.... 

http://support.sas.com/kb/44/233.html

 

Kannan Deivasigamani
Tom
Super User Tom
Super User

You probably do not want to use this trick.  First it does not take into account the rules for centuries. Years that are divisible by 100 but not divisible by 400 are NOT leap years. You can probably figure out a way to use the built in date manipulation functions to do what you want.  For example to find the number of days in a year you could do:

 

%let days_in_year = %sysevalf("01JAN%eval(&year+1)"d - "01JAN&YEAR"d) ;

 

But to the specific question of how to interpret the expression:

 

(4*INT(&Year/4)=&Year)

The function call INT(&YEAR/4) will divide the year value by 4 and keep only the integer part of the result.  If you then multiple by 4 you will only get the same number back when the year was exactly divisible by 4.  So this will be true when YEAR is a multiple of 4.  SAS returns 1 for true and 0 for false when evaluating a logical expression in an equation.  You could do the same thing a little clearer using the MOD() function.  

 

(0=MOD(&YEAR,4))

 

But there are other issues with this %LET statement.

First it is generating the SAS code to call the INT() function instead of evaluating the expression itself.  For example try this code:

    %let year=2015 ;
    %let year=183<= A < 365+(4*INT(&year/4)=&year) ;
    %put &year ;

The result is that YEAR contains the expression:  183<= A < 365+(4*INT(2015/4)=2015)

That means that if you use this macro variable in a data step expression the INT() function is re-run each time through the data step.

 

Second it is probably not good practice to store it back into the same macro varaible that previously just had the digit string for the year.

 

 

 

Astounding
PROC Star

As a macro language statement, this does nothing useful.  Macro language evaluates comparisons from left to right.  So the first evaluation is:

 

183 <= A

 

This is not a reference to a variable named "A", it is just the letter "A".  So the comparison will be either true or false depending on your operating system (ASCII vs. EBCDIC).  True comparisons return a 1, and false comparisons return a zero.  So midway through the comparisons, macro language is looking at:

 

1 < 365 + (4*INT(&Year/4)=&Year)

 

This comparison will always be true, and will therefore return a 1.  So the result of your original statement should always be assigning &YEAR a value of 1 (possibly adding + (4*INT(&Year/4)=&Year) aftwards ... I'm not able to verify that right now).

 

I vote for the recommendation to examine INTNX.  Properly used in a DATA step, it can return, for example, a SAS date equivalent to the same day of the year, X years in the future.

 

Good luck.

Patrick
Opal | Level 21

@Astounding

I believe you've missed that the expression doesn't get evaluated on SAS macro level. It's simply populating a macro variable which I assume is then used in a data step where the expression evaluates on SAS Base language level.

Patrick
Opal | Level 21

As @PaigeMiller already wrote: SAS provides a whole set of calendar functions which do all the magic for you. No need to try and code this.

 

I suggest you ask the person who provided this code what it's supposed to do - and then re-write the intended logic using SAS calendar functions.

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

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