Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

javascript to find leap year

How can I get the code below to work when I have a month of february? Currently it is getting to the day and then stopping before getting to the if to determine whether it is a leap year.

 if (month == 2) {     if (day == 29) {         if (year % 4 != 0 || year % 100 == 0 && year % 400 != 0) {             field.focus();              field.value = month +'/' +  '';         }     }     else if (day > 28) {         field.focus();              field.value = month +'/' +  '';     } } 
like image 912
Juan Almonte Avatar asked Nov 17 '11 22:11

Juan Almonte


People also ask

How do you check if a year is a leap year JavaScript?

Example 2: Check Leap Year Using newDate() If a month of February contains 29 days, it will be a leap year. The new Date(2000, 1, 29) gives the date and time according to the specified arguments. The getDate() method returns the day of the month.

How do you check if a year is a leap year?

A leap year has 366 days (the extra day is the 29th of February), and it comes after every four years. To check if a year is a leap year, divide the year by 4. If it is fully divisible by 4, it is a leap year. For example, the year 2016 is divisible 4, so it is a leap year, whereas, 2015 is not.

Is 2022 a leap year?

Why 2022 isn't a leap year. The last leap year was 2020. So 2024 will be our next leap year, a 366-day-long year, with an extra day added to our calendar (February 29). We'll call that extra day a leap day.


2 Answers

It's safer to use Date objects for datetime stuff, e.g.

isLeap = new Date(year, 1, 29).getMonth() == 1 

Since people keep asking about how exactly this works, it has to do with how JS calculates the date value from year-month-day (details here). Basically, it first calculates the first of the month and then adds N -1 days to it. So when we're asking for the 29th Feb on a non-leap year, the result will be the 1st Feb + 28 days = 1st March:

> new Date(2015, 1, 29) < Sun Mar 01 2015 00:00:00 GMT+0100 (CET) 

On a leap year, the 1st + 28 = 29th Feb:

> new Date(2016, 1, 29) < Mon Feb 29 2016 00:00:00 GMT+0100 (CET) 

In the code above, I set the date to 29th Feb and look if a roll-over took place. If not (the month is still 1, i.e. February), this is a leap year, otherwise a non-leap one.

like image 153
georg Avatar answered Sep 23 '22 18:09

georg


Compared to using new Date() this is is around 100 times faster!

Update:

This latest version uses a bit test of the bottom 3 bits (is it a multiple of 4), as well as a check for the year being a multiple of 16 (bottom 4 bits in binary is 15) and being a multiple of 25.

ily = function(y) {return !(y & 3 || !(y % 25) && y & 15);}; 

http://jsperf.com/ily/15

It is slightly faster again than my previous version (below):

ily = function(yr) {return !((yr % 4) || (!(yr % 100) && (yr % 400)));}; 

http://jsperf.com/ily/7

It is also 5% faster, compared to the already fast conditional operator version by broc.seib

Speed Test results: http://jsperf.com/ily/6

Expected logic test results:

alert(ily(1900)); // false alert(ily(2000)); // true alert(ily(2001)); // false alert(ily(2002)); // false alert(ily(2003)); // false alert(ily(2004)); // true alert(ily(2100)); // false alert(ily(2400)); // true 
like image 25
Gone Coding Avatar answered Sep 20 '22 18:09

Gone Coding