0

I'm trying to put a leap year checker in my Age calculator. It worked for sometime and now it outputs "This is a leap year" every time I select a date. What am I doing wrong?? Thank you!

var year;

function ageCalculator() {
  var userinput = document.getElementById("DOB").value;
  var dob = new Date(userinput);

  if (userinput == null || userinput == '') {
    document.getElementById("message").innerHTML = "**Choose a date please!";
    return false;
  } else {
    //calculate month difference from current date in time
    var month_diff = Date.now() - dob.getTime();

    //convert the calculated difference in date format
    var age_dt = new Date(month_diff);

    //extract year from date
    var year = age_dt.getUTCFullYear();
    calYear();
    //now calculate the age of the user
    var age = Math.abs(year - 1970);

    //display the calculated age
    return document.getElementById("result").innerHTML =
      "Age is: " + age + " years. ";
  }
}

function calYear() {
  var yr = year;
  var yr = document.getElementsByName("year");
  if (yr % 400 == 0 || (yr % 100 != 0 && yr % 4 == 0)) {
    window.alert("This is not leap!");
  } else {
    window.alert("This is a leap!");
  }
}
<input type="text" id="DOB" />
<button type="button" onclick="ageCalculator()">Calculate</button>
<span id="message"></span><br/>
<span id="result"></span>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
  • Why do you want a leap year checker? In case your visitor is born on the 29th of Feb? [DOB](https://stackoverflow.com/a/14838925/295783) – mplungjan Feb 16 '21 at 07:46
  • 2
    (Offtopic) PS, try always not to use specificities like `document.getElementById("DOB").value` inside a function that does what it says. Instead pass arguments and be happy knowing you can reuse that function with any other elements in any part of your application. `ageCalculator(inputBirth) { /*calc*/ return outputAge; }` – Roko C. Buljan Feb 16 '21 at 07:48
  • (Offtopic) Avoid using variables that end up polluting the global Window scope (`var year`). At some point try to `console.log(window.year)` - that's not good. – Roko C. Buljan Feb 16 '21 at 07:54
  • `document.getElementsByName("year")` is an **Element** not its value! Also, `Element.value` returns **always** a string - and it's your task as a developer to convert strings (or know typecasting by heart) to an integer or a float as necessary. – Roko C. Buljan Feb 16 '21 at 07:57
  • Please [edit] your Question and create a [mcve]. – Roko C. Buljan Feb 16 '21 at 08:00
  • Be careful using `new Date(userinput)` where `userinput` is an **invalid ISO8601** string. You can easily get out false positives. – Roko C. Buljan Feb 16 '21 at 08:02
  • @RokoC.Buljan it is worse: `document.getElementsByName("year");` is a collection – mplungjan Feb 16 '21 at 08:03
  • `Date.now() - dob.getTime()` cannot by any means be what the comment says: *`calculate month difference`* that's absolutely not true. – Roko C. Buljan Feb 16 '21 at 08:09
  • Welcome to Stack Overflow! Please visit the [help], take the [tour] to see what and [ask]. Do some research, search for related topics on SO; if you get stuck, post a [mcve] of your attempt, noting input and expected output using the `[<>]` snippet editor. – mplungjan Feb 16 '21 at 08:09

5 Answers5

1
  • document.getElementsByName("year") is a Collection not an Element value! Also, Element.value returns always a string - and it's your task as a developer to convert strings (or know typecasting by heart) to an integer or a float as necessary.
  • Don't put specifics into a function (like i.e: document.getElementById etc) make it reusable!
  • Avoid using variables that end up polluting the global Window scope (var year). At some point try to console.log(window.year) and you'll see why.
  • Don't call a function calYear() ? if it returns a string. Instead call it properly: isLeap() and do what it says! Return a Boolean value.
    Only at the point you use/call that function in your UI - decide there the appropriate string you want to show. Don't limit yourself.
  • Be always careful while using new Date(someUserInput) where someUserInput might be an invalid ISO8601 string. You can easily get false positives.
  • PS: Date.now() - dob.getTime() cannot by any means be what your comment says: "calculate month difference" that's absolutely not true - Be careful when writing your comments and when naming your functions.

/**
 * @param {integer} year
 * @return {boolean} - True if year is leap year
 */
const isLeap = (year) => (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;

/**
 * @param {string} DOBString - A valid ISO8601 dateString
 * @return {integer} - Age
 */
const calcAge = (DOBString) => {
  const UTC_DOB = new Date(DOBString);
  if (!DOBString || isNaN(UTC_DOB)) return;
  const UTC_today = new Date();
  const m = UTC_today.getUTCMonth() - UTC_DOB.getUTCMonth(); // Month diff
  let age = UTC_today.getUTCFullYear() - UTC_DOB.getUTCFullYear();
  if (m < 0 || (m === 0 && UTC_today.getUTCDate() < UTC_DOB.getUTCDate())) age--;
  return age;
};

// UI/Page/View specific scripts:

const EL_DOB = document.querySelector("#DOB");
const EL_result = document.querySelector("#result");
const EL_leap = document.querySelector("#leap");
const UI_showAgeResult = () => {
  const age = calcAge(EL_DOB.value);
  const UTC_DOB = new Date(EL_DOB.value);
  const is_leap = isLeap(UTC_DOB.getUTCFullYear());
  EL_result.textContent = age ? age : "Insert a valid date";
  EL_leap.textContent =  is_leap ? "Born on a leap year! so cool" : "";
};

// Do it on input Event
EL_DOB.addEventListener("input", UI_showAgeResult);
// And if needed on page init
UI_showAgeResult();
<input id="DOB" type="text" value="2000-02-29"/>
<span id="result"></span><br>
<span id="leap"></span>

Important:
notice that if user Date Of Birth is say "2000-02-29", and say today's date is "2001-02-28" the result age will be arguably-correctly 0.
Only if date is "2001-03-01" will result as 1 y of age.

Kudos:
Slightly modified @naveen answer's code for calculating dates diff → age.

Roko C. Buljan
  • 196,159
  • 39
  • 305
  • 313
0

I suggest you look at this version

Calculate age given the birth date in the format YYYYMMDD

To fix YOUR code we need to pass the year to the function and not try to use a non-existing year field

If there was such a field, you could access its value with document.querySelector("[name=year]").value since document.getElementsByName is a collection and the value would be document.getElementsByName("year")[0].value

So what did I do?

  • passed the DOB year to the leap function
  • calculated the age from the year of the date difference

I tested with 2000-02-29 and 2001-02-28

NOTE the script ALSO works with 02/29/2016 but not with 29/02/2016 (European format)

var year;

function ageCalculator() {
  var userinput = document.getElementById("DOB").value;
  var dob = new Date(userinput);

  if (isNaN(dob)) {
    document.getElementById("message").innerHTML = "**Choose a date please!";
    return false;
  } else {

    //extract year from date
    var year = dob.getFullYear();
    console.log(year)
    testLeap(year);

    //calculate difference from current date in milliseconds
    var date_diff = Date.now() - dob.getTime();

    //convert the calculated difference in date format
    var age_dt = new Date(date_diff);

   //now calculate the age of the user
    var age = Math.abs(1970 - age_dt.getFullYear());

    //display the calculated age
    return document.getElementById("result").innerHTML =
      "Age is: " + age + " years. ";
  }
}

function testLeap(yr) {
  const isLeap = (yr % 400 == 0 || (yr % 100 != 0 && yr % 4 == 0)) 
  alert(isLeap ? "This is a leap!" : "This is not a leap!");
}
<input type="text" id="DOB" />
<button type="button" onclick="ageCalculator()">Calculate</button>
<span id="message"></span><br/>
<span id="result"></span>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
0

If you only need a function to check if the input year is a leap year or not, you can use Date object:

function isLeapYear(year) {
    // year, monthIndex, day
    return new Date(year, 1, 29).getFullYear() === year;
}
pritam
  • 2,452
  • 1
  • 21
  • 31
-2

this is function to check if this year is leap year

function isLeapYear(year){
 return (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;
}
isLeapYear(2000) //true
isLeapYear(2001) // false

EDIT: so the problem is in document.getElementsByName("year") i think you should have a HTML named year which is have the year value

<input type="number" name="year" />
Jethro91
  • 537
  • 4
  • 7
  • `document.getElementsByName("year");` is not a value - that is the main problem here – mplungjan Feb 16 '21 at 08:14
  • I did not comment for you to add my comment to your answer. Also your interpretation of my comment was not useful. Please see my answer for a complete answer – mplungjan Feb 16 '21 at 08:48
-2

Here's another Method I can make sure it will works

function ageCalculator() {
  var userinput = document.getElementById("DOB").value;
  var dob = new Date(userinput);

  if (userinput == null || userinput == '') {
    document.getElementById("message").innerHTML = "**Choose a date please!";
    return false;
  } else {
    //calculate month difference from current date in time
    var month_diff = Date.now() - dob.getTime();

    //convert the calculated difference in date format
    var age_dt = new Date(month_diff);

    //extract year from date
    var year = age_dt.getUTCFullYear();
    calYear(year);
    //now calculate the age of the user
    var age = Math.abs(year - 1970);

    //display the calculated age
    return document.getElementById("result").innerHTML =
      "Age is: " + age + " years. ";
  }
}

function calYear(yr) {
  if (yr % 400 == 0 || (yr % 100 != 0 && yr % 4 == 0)) {
    window.alert("This is not leap!");
  } else {
    window.alert("This is a leap!");
  }
}

Try updating the callYear if condition assuming yr> 1000 and yr < 8000

function calYear(yr) {
  if ((yr % 4 === 0 && yr % 100 !== 0) || yr % 400 === 0 ) {
    window.alert("This is not leap!");
  } else {
    window.alert("This is a leap!");
  }
}
Jethro91
  • 537
  • 4
  • 7
  • This also outputs "This is a Leap" on my webpage no matter what date is selected.... i'm not sure why it worked for sometime then stopped. I wanted "This is a leap!" only to appear when a user selected the date 29/02/2016 for example – Paul Egan Feb 16 '21 at 08:51
  • try to edit callyear if condition into this asuming yr > 1000 yr < 8000 (yr % 4 === 0 && yr% 100 !== 0) || yr % 400 === 0; – Jethro91 Feb 16 '21 at 09:03