【问题标题】:Leap year checker in javascriptjavascript中的闰年检查器
【发布时间】:2021-05-19 01:38:45
【问题描述】:

我正在尝试在我的年龄计算器中添加闰年检查器。它工作了一段时间,现在每次我选择日期时都会输出“这是闰年”。我究竟做错了什么??谢谢!

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>

【问题讨论】:

  • 为什么需要闰年检查器?如果您的访客出生在 2 月 29 日? DOB
  • (Offtopic) PS,尽量不要在函数中使用像 document.getElementById("DOB").value 这样的特殊性。相反,传递参数并高兴地知道您可以在应用程序的任何部分中将该函数与任何其他元素重用。 ageCalculator(inputBirth) { /*calc*/ return outputAge; }
  • (Offtopic) 避免使用最终污染全局 Window 范围的变量 (var year)。在某些时候尝试console.log(window.year) - 这不好。
  • document.getElementsByName("year") 是一个 元素 而不是它的价值!此外,Element.value 返回 always 字符串 - 作为开发人员,您的任务是根据需要将字符串(或熟记类型转换)转换为整数或浮点数。
  • edit您的问题并创建一个minimal reproducible example

标签: javascript html function output leap-year


【解决方案1】:
  • document.getElementsByName("year") 是一个集合而不是一个元素值!此外,Element.value 总是返回一个字符串 - 作为开发人员,您的任务是根据需要将字符串(或熟记类型转换)转换为整数或浮点数。
  • 不要将细节放入函数中(例如:document.getElementById 等)使其可重用!
  • 避免使用最终污染全局 Window 范围 (var year) 的变量。在某个时候尝试console.log(window.year),你就会明白为什么。
  • 不要调用函数calYear() 如果它返回一个字符串。而是正确地调用它:isLeap() 并按照它所说的去做!返回一个布尔值。
    仅在您在 UI 中使用/调用该函数时 - 确定您要显示的适当字符串。不要限制自己。
  • 使用new Date(someUserInput) 时请务必小心,其中someUserInput 可能是无效的ISO8601 字符串。您很容易得到误报。
  • PS:Date.now() - dob.getTime() 绝不可能是您的评论所说的:“计算月差” 这绝对不是真的 - 编写 cmets 和命名函数时要小心。

/**
 * @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>

重要提示:
请注意,如果用户 出生日期 是“2000-02-29”,并且说 今天 的日期是“2001-02-28”,则结果年龄将为可以说是正确的0.
仅当日期为“2001-03-01”时,才会产生1 y 的年龄。

荣誉:
稍微修改了@naveen答案的代码,用于计算日期差异→年龄。

【讨论】:

  • 很好的答案先生
【解决方案2】:

我建议你看看这个版本

Calculate age given the birth date in the format YYYYMMDD

要修复您的代码,我们需要将年份传递给函数,而不是尝试使用不存在的年份字段

如果有这样一个字段,您可以使用 document.querySelector("[name=year]").value 访问它的值,因为 document.getElementsByName 是一个集合,值将是 document.getElementsByName("year")[0].value

那我做了什么?

  • 将 DOB 年传递给闰函数
  • 从日期差的年份计算年龄

我用 2000-02-29 和 2001-02-28 测试

注意脚本也适用于 02/29/2016,但不适用于 29/02/2016(欧洲格式)

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>

【讨论】:

  • 这段代码仍然输出“这是一个飞跃!”无论我在网页上选择什么日期
  • 不,它没有。试试 2000-02-29 和 2001-02-28
  • 29/02/2016 不是在此脚本中输入的有效日期。然后我们需要修复输入
  • 29/02/2016 是欧洲格式,JS 日期不支持。您可以尝试 02/29/2016 进行测试,我们需要更多代码将 DD/MM/YYYY 格式化为 MM/DD/YYYY 以使脚本正常工作
【解决方案3】:

如果你只需要一个函数来检查输入年份是否是闰年,你可以使用 Date 对象:

function isLeapYear(year) {
    // year, monthIndex, day
    return new Date(year, 1, 29).getFullYear() === year;
}

【讨论】:

    【解决方案4】:

    这是检查今年是否是闰年的功能

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

    编辑: 所以问题出在 document.getElementsByName("year") 我认为你应该有一个名为 year 的 HTML,它具有年份值

    <input type="number" name="year" />
    

    【讨论】:

    • document.getElementsByName("year"); 不是一个值 - 这是这里的主要问题
    • 我没有评论让您将我的评论添加到您的答案中。您对我的评论的解释也没有用。完整答案请看我的回答
    【解决方案5】:

    这是我可以确保它有效的另一种方法

    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!");
      }
    }
    

    如果条件假设,请尝试更新 callYear yr> 1000 和 yr

    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!");
      }
    }
    

    【讨论】:

    • 无论选择什么日期,这也会在我的网页上输出“这是一个飞跃”......我不知道为什么它工作了一段时间然后停止了。我想要“这是一个飞跃!”仅在用户选择日期 29/02/2016 时出现
    • 尝试编辑 callyear 如果条件为这个假设 yr > 1000 yr
    猜你喜欢
    • 2011-12-31
    • 1970-01-01
    • 2013-04-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-01
    • 1970-01-01
    • 2022-12-10
    相关资源
    最近更新 更多