-2

I wrote this code for calculating a leap year in JavaScript and apparently it's correct but I don't understand why, because it seems logical to me to say: if(year%400===0).... but it's incorrect if I do that why??

code:

function isLeap(year) {
    if (year % 4 === 0 && year % 100 !== 0) {
        if (year % 400) /*this is teh part I am taklking about*/ {
            return "Leap year.";
        }
    } else {
        return "Not leap year.";
    }
}
Álvaro González
  • 142,137
  • 41
  • 261
  • 360
ivanka
  • 1
  • 1
    `if (a)` means `a` is tested for being truthy. In the case of a number, anything other than zero is truthy. With that out of the way, a year that is not divisible by 100 is definitely not divisible by 400, so that condition will always be true. Which means the test isn't correct. –  May 14 '20 at 14:51
  • 2
    The year 2000 was a leap year. – QuentinUK May 14 '20 at 14:53
  • Does this answer your question? [javascript to find leap year](https://stackoverflow.com/questions/8175521/javascript-to-find-leap-year) – inetphantom May 14 '20 at 15:22
  • @inetphantom - I think the goal here is to understand what's happening in the OP's own code, not just to know how to handle leap years. – T.J. Crowder May 14 '20 at 15:27

1 Answers1

1

The code isn't correct, and part of the problem is indeed the line you mentioned, but the real problem is that the rules aren't being applied correctly.

You asked about this line:

if (year % 400)

That's perfectly valid. The value (a number) will be converted to a boolean: Any number other than 0 (or NaN) is "truthy"; 0 and NaN are "falsy." So that line is basically the same as:

if (year % 400 !== 0)

...except for the edge case where year is NaN (and so year % 400 is NaN).

But the code doesn't handle leap years correctly, because for years that are evenly divisible by 4 you need to say they're leap years if they're not evenly divisible by 100 or they are evenly divisible by 400. You're applying the 400 rule in the wrong place.

You're also not returning a string in all of your branches, but the branch where you aren't will never be taken because if year % 100 !== 0 then year % 400 will always be truthy.

The minimal change is:

function isLeap(year) { 
    if (year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0)) {
        return "Leap year.";
    } else {
        return "Not leap year.";
    }      
}

...or with the conditional operator:

function isLeap(year) { 
    return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0)
        ? "Leap year."
        : "Not leap year.";
}

Live Example:

function isLeap(year) { 
    return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0)
        ? "Leap year."
        : "Not leap year.";
}
function test(year) {
    console.log(year, isLeap(year));
}
test(1971); // No
test(1972); // Yes
test(2000); // Yes! (The 400 rule kicks in)
test(2100); // No
T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875