How to know if it’s a leap year
It always happens : you have some calculation to do with a date and you forget to calculate those friggin’ leap years. Here’s how to do it cleanly.
The first way
Almost every one use this simple rule : if it’s divisible by 4, it’s a leap year. So the code is
-
var isLeap = theYear % 4 == 0
Wait a minute, I forgot something! If it’s not divisible by 100 but by 400 it is not a leap year… or maybe divisble by 100 and not by 400…
I can’t remember that! Let’s do it another way.
The one and only way
-
var isLeap = new Date(theYear,1,29).getDate() == 29;
Nice! That’s something simple that I enjoy. Let’s dissect it.
-
new Date(theYear, 1, 29)
This line simply create a date object that is initialized with the variable theYear. 1 is the month. As in java, the months are 0 = january and 11 = december (I hate that!). 29 is the last day of february when it’s a leap year.
-
.getDate()
Returns the date part of a date (sic!). It means that for May 23, 2007, it will return 23.
-
== 29
That’s the magic part of it. As I said in Mastering the date object in Javascript, there’s a special twist that let you work with dates differently than in most of the languages that I used before. When you initialize a date at the 29th day of february on a non-leap year, it will simply use the date March 1, 2007. So a call to the getDate() function would return 1 and not 29.


RSS without the echo chamber
Doesn’t this run the risk of creating unnecessary objects?
Isn’t a better solution to use the mathematical method and stick it in a util library?
@Seth
The unnecessary Date object will be deleted as soon as possible. It would be better to have it in a util library but the problem is that we don’t always have that type of library in hands when we code. I must admit that I really enjoy the shortness of the code…
I wouldn’t exactly say it’s the “only” way, but it does seem like a good idea to reuse the already-implemented and presumably debugged leap year logic via the Date object. Good idea, thanks.
[…] How to know if it’s a leap year var isLeap = new Date(theYear,1,29).getDate() == 29; When you initialize a date at the 29th day of february on a non-leap year, it will simply use the date March 1, 2007. So a call to the getDate() function would return 1 and not 29. (tags: Date/Time) […]
Just be aware of the date limitation with the year: minimum=1970
Am I missing something or shouldn’t your code be:
var isLeap = new Date(theYear,2,29).getDate() == 29;
As I said in the post :
“As in java, the months are 0 = january and 11 = december (I hate that!).”
January is 0, february is 1 and march is 2…
function isLeap(theYear) {
if (theYear % 400 == 0) return true;
if (theYear % 100 == 0) return false;
if (theYear % 4 == 0) return true;
return false;
}
I think the code is simple!
The following is someting I had developed myself, and is very similar to what Katatunix has. However, it benefits from executing the most significant evaluations first, and thereby is more efficient- 3 of every 4 years will only do the first comparison. Also, it is one statement, so that also improves it.
function isLeap(theYear) {
return (theYear % 4 == 0)? (theYear % 100 == 0)? (theYear % 400 == 0): true:false:true:false;
}
@Gentle Geek
thanks, I’ll take a look at it and update the post when I’ll have the time.
The solution you have provided does not work.
Thanks for checking it Giri… I had mistyped it here- I had typed one more “:” and one less “?” than I should have typed. This is the corrected version:
function isLeap(theYear) {
return (theYear % 4 == 0)? (theYear % 100 == 0)? (theYear % 400 == 0)? true:false:true:false;
}
function isLeap(theYear) {
return (theYear % 4 == 0)? (theYear % 100 == 0)? (theYear % 400 == 0)? true:false:true:false;
}
that’s too much kludge code
best method:
function isLeap(intYear){return ((intYear > 1582) && ((!(intYear%400)) || ((!!(intYear%100)) && (!(intYear%4)))));}
this takes into count when leapss years were added and does other dates correctly as well
The point was that
new Date(theYear,1,29).getDate() == 29
was the easiest way of doing it. No hard to read parenthesis or special move, just a simple date object creation…