https://en.wikipedia.org/wiki/Leap_year
*** Please review the "how to post a question" guidance presented underneath the Post my question button when posting a question. The answers you get will rely on the information you post, hence using the body of the text to explain your issue, showing test data in the form of a datastep, showing what the output should look like etc. will yield you good answers. I mean a simply google search results in first place to:
https://blogs.sas.com/content/sasdummy/2016/02/19/calculate-leap-year-in-sas/
Leapyears are years that can be divided by four, except every 100th year, but including every 400th year. Use the mod() function for this:
data test;
input year;
leapyear = (mod(year,4) = 0) and ((mod(year,100) ne 0) or (mod(year,400) = 0));
cards;
2018
2016
2000
1900
;
run;
Note that a simple fomula will perform better than a chain of if/else conditions.
Not quite:
data test; input year; leapyear = (mod(year,4) = 0) and ((mod(year,100) ne 0) or (mod(year,400) = 0)); date= intnx('month',mdy(2,1,year),0,'e'); format date date9.; cards; 2018 2016 2000 1900 2400 3000 4000 ; run;
Your algorithm will indicate that year 4000 (and 8000, 12000, 16000 and 20000) is a leap year incorrectly. Probably not of practical significance for most things but I ran into this when I had to convince some people that the SAS dates I was working with would be Y2K compliant and played around with the date functions and date values in SAS to push the limits a bit.
INTNX doesn't want to deal with years past 20000 (currently).
So the formula needs an extension:
leapyear = (mod(year,4) = 0) and ((mod(year,100) ne 0) or (mod(year,400) = 0 and mod(year,4000) ne 0));
untested, as I'm on my tablet right now.
Further research has brought me to the conclusion that
so it's still up to the user to decide if to follow it or not.
30 days hath September ....
463 data _null_; 464 do yr=2016 to 2020 ; 465 leapyr = 29 = day(mdy(3,1,yr)-1); 466 put yr= leapyr= ; 467 end; 468 run; yr=2016 leapyr=1 yr=2017 leapyr=0 yr=2018 leapyr=0 yr=2019 leapyr=0 yr=2020 leapyr=1
You're missing some refinement as noted in above comments:
1) These extra days occur in years which are multiples of four (with
the exception of centennial years not divisible by 400).
2) A rule has be proposed to make the year 4000 not a leap year
as a correction.
@gkeeler wrote:
You're missing some refinement as noted in above comments:
1) These extra days occur in years which are multiples of four (with
the exception of centennial years not divisible by 400).
2) A rule has be proposed to make the year 4000 not a leap year
as a correction.
Just include more dates in the list to find out if SAS is implementing those rules properly. Looks like it does the 400 multiples right but it still considers 4,000 as a non-leap year. SAS only has a little less than 1,980 years to adjust how they handle years that are multiples of 4000, assuming that the proposed rule is adopted.
data _null_;
do yr=2000,2016 to 2020,2100,4000 ;
leapyr = 29 = day(mdy(3,1,yr)-1);
put yr= leapyr= ;
end;
run;
yr=2000 leapyr=1 yr=2016 leapyr=1 yr=2017 leapyr=0 yr=2018 leapyr=0 yr=2019 leapyr=0 yr=2020 leapyr=1 yr=2100 leapyr=0 yr=4000 leapyr=0
SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!
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.
Ready to level-up your skills? Choose your own adventure.