编写一个JavaScript程序来计算闰年

Writing a JavaScript program to calculate a leap year

本文关键字:程序 JavaScript 计算 闰年 一个      更新时间:2023-09-26

我正在编写一个JavaScript程序,该程序接收用户键入的日期并确定给定日期在一周中的哪一天。我能够让程序接受日期。我使用 debug 语句打印了日、月、年和世纪的值,以确保程序正确获取值,到目前为止,它们就是这样。

我还有一个名为 totalNumDays 的调试变量,它存储每个月由于该值不同而计算的天数。(1 月有 31 天,4 月有 30 天,2 月有 28 或 29 天)。我遇到的问题是让二月份的数字正确

我所做的是创建一个包含 31 天的所有月份的数组:

//1 = January, 3 = March, 5 = May,..., etc.
var monthNumsWith31 = [1, 3, 5, 7, 8, 10, 12];

然后稍后我使用 for 循环来迭代以确定天数。我在这里尝试了几种不同的东西。我认为最有意义的是:

for(var i = 0; i < monthNumsWith31.length; i++)
{
   if(month == monthNumsWith31[i])
   {
      totalNumDays = 31;
   }
   else
   {
      if(month == 2 && isLeapYear() == true)
      {
         totalNumDays = 29;
      }
      else if(month == 2 && isLeapYear() == false)
      {
         totalNumDays = 28;
      }
      else
      {
         totalNumDays = 30;
      }
   }

我尝试了一大堆不同的东西,但似乎无法让它存储 2 月份的正确天数。我甚至尝试创建第二个monthNumsWith30数组,并使用两个不同的 for 循环来迭代这两个数组,并为 30 天和 31 天的月份设置适当的天数。我认为问题可能出在我的isLeapYear()功能上。这是isLeapYear()的代码。请注意,year是全局的,因此函数可以访问它。

function isLeapYear() {
    if(year % 4 == 0)
    {
       if(year % 100 == 0)
       {
          if(year % 400 == 0)
          {
             return true;
          }
          else
          {
             return false;
          }
       }
       else
       {
          return true;
       }
    }
    else
    {
       return false;
    }
}

我试图遵循确定一年是否是闰年的公式。公式可以在这里显示:https://gyazo.com/9e4b7fb92014d1e27315807c188fd5e0

有谁知道为什么我的函数没有做它应该做的事情?谢谢。

更新我现在让它正常工作,以计算每个月的正确天数。但是,我遇到了另一个问题。

为了找出给定日期发生在一周中的哪一天,我使用了泽勒全等。我使用的特定公式是((26M - 2) / 10 + D + Y + Y/4 + C/4 + 5C) MOD 7其中MDY正是它们看起来的样子,C是世纪(一年的前两位数)。算法中有一部分声明

IF Month < 3 THEN
   Year = Year - 1
   Month = Month + 10
ELSE
   Month = Month - 2
END IF

我让所有这些工作似乎都是正确的。我输入了许多调试语句以确保它获得正确的值,但由于某种原因,计算机错误地计算了表达式。

此算法将给出一个介于 0 和 6 之间的数字。 0 表示星期日,1 表示星期一,依此类推。例如,取日期 2/15/16。这个日期发生在星期一。2016年2月15日,星期一。

在我的程序中,我有以下代码

var weekdayIndex = (Math.floor((26 * monthVal) - 2 / 10) + dayVal + 
    yearVal + Math.floor(yearVal / 4) + Math.floor(centuryVal / 4) +
    (5 * centuryVal)) % 7;

当这个表达式运行时,它应该等于 1 ,但由于某种原因它等于 0 。我手工计算,一遍又一遍地评估每个单独的表达式,并不断得到1。手工执行此操作,我得到了要(31 + 15 + 15 + 3 + 5 + 20) % 7的数字。当我直接将此表达式放入计算机时(没有所有变量名称和 Math.floor 表达式,只有数字),它正确地获取了值。我不知道为什么当我使用变量名称和表达式时它是不正确的。有什么想法吗?

你的函数没问题,除了一件简单的事情:你缺少年份参数!

function isLeapYear(year) {
  return year % 4 == 0 &&
    (year % 100 !== 0 || year % 400 === 0);
}

但是,使用扩展语法也可以:

function isLeapYear(year) {
    if(year % 4 == 0)
    {
       if(year % 100 == 0)
       {
          if(year % 400 == 0)
          {
             return true;
          }
          else
          {
             return false;
          }
       }
       else
       {
          return true;
       }
    }
    else
    {
       return false;
    }
}

isLeapYear(1900)收益率false,如预期的那样,2000 true,1996 true,1997 false

对我来说似乎是合法的。

我认为你的逻辑相当可疑。 我使用以下函数来确定给定年份是否为闰年:

CsiLgrDate.leap_year = function (year)
{ return ((year % 4 === 0 && year % 100 !== 0) || year % 400 === 0); };

你的函数是正确的,错误是因为 month 的 javascript Array是零索引的。

更改此行:

var monthNumsWith31 = [1, 3, 5, 7, 8, 10, 12];

对此:

var monthNumsWith31 = [0, 2, 4, 6, 7, 9, 11];

并从所有月份参考中减去一个(二月是数组索引 1


您可以通过在控制台上键入 (new Date()).getMonth() 来对其进行测试:您将看到 march == 2 .

希望对您有所帮助。

在这里试一试。我假设你才刚刚开始。我们可以避免很多嵌套的if语句。此外,您需要开始养成使用三等号 (===) 的习惯,因为它会进行类型检查,并且不会对"真实"值做奇怪的事情。

首先,查看您的isLeapYear函数。当你检查 if 语句并使用相等运算符来比较它们时,它将返回一个 true 或 false,所以如果我们没有做奇怪的事情,我们期望 true 是假的(尽管也有简单的方法可以做到这一点)我们实际上可以只返回表达式以获得真或假, 而不是如果您的表达式为真或假,则不需要返回 true 或 false。

作为论据在一年中传递而不是从父母的范围内获取它也可能是值得的。但在这种情况下,我敢肯定,这实际上并不重要。

&&将检查语句是否为真,然后执行下一个表达式。如果你期望一切都是真的,你可以把它链起来,因为如果一件事是假的,那么一切都是假的。所以不需要编写嵌套的 if 语句。

function checkLeapYear(yearToCheck) {
    return yearToCheck%4 === 0 && yearToCheck%100 === 0 && yearToCheck%400 === 0;
}

因此,循环遍历数组有点昂贵。如果您开始遍历数组中的数组,您可能会了解到这一点。但幸运的是,对于此示例,我们甚至不需要它。

这是一个开关语句。如果你有需要等于相同事物的值,这将非常方便。但你可能会从很多人那里听到我写我的方式是错误的,你永远不应该让一个案子失败。我不同意这些人的观点,因为我认为这是一个很好的例子,说明你什么时候想这样做。

此开关将采用一个变量,在本例中为月份。将其与案例中的值进行比较,然后执行案例的代码。它将在没有break;的情况下落入下一个情况,因为我们希望1, 3, 5, 7, 8, 10, 12totalNumDays = 31我们将其设置为最低情况,其余的落入。

但是,如果month等于 2,我们希望闰年totalNumDays 29 或 28。三元运算符 它基本上就像一个速记 if 语句。你给它一个表达式,在本例中是checkLeapYear函数,然后是一个启动三元运算符的?。然后是当它为真时的值,在这种情况下我们希望它等于 29。然后对于假值使用:然后输入你想要的假值,在本例中为 28。

在 switch 语句中,default 只是意味着在没有匹配项的情况下执行此操作。这使totalNumDays等于30。这可能有点危险,因为如果我们使月份等于 13 或"A",它仍然会使totalNumDays等于 30。但是,为每一种可能性做好准备并不是我现在太关心的事情。

switch(month) {
  case 1:
  case 3:
  case 5:
  case 7:
  case 8:
  case 10:
  case 12:
    totalNumDays = 31;
    break;
  case 2:
    totalNumDays = checkLeapYear(year) ? 29 : 28;
    break;
  default:
    totalNumDays = 30;
    break;
}

无论如何,我希望这有所帮助,而不是太多。至于为什么你的代码不起作用。我认为这可能是因为您的循环从第 0 个月开始。这将是30天的月份。

如果在 isLeapYear 调用和函数声明中使用 year 参数,则代码实际上有效。

这是与发布完全相同的代码(好吧,我添加了一个缺失的结束},我认为这是一个发布遗漏):

// Set some test values
var monthNumsWith31 = [1, 3, 5, 7, 8, 10, 12];
var month = 2;
var year = 2000
for(var i = 0; i < monthNumsWith31.length; i++)
{
   if(month == monthNumsWith31[i])
   {
      totalNumDays = 31;
   }
   else
   {
      if(month == 2 && isLeapYear(year) == true)
      {
         totalNumDays = 29;
      }
      else if(month == 2 && isLeapYear(year) == false)
      {
         totalNumDays = 28;
      }
      else
      {
         totalNumDays = 30;
      }
   }
}
function isLeapYear(year) {
    if(year % 4 == 0)
    {
       if(year % 100 == 0)
       {
          if(year % 400 == 0)
          {
             return true;
          }
          else
          {
             return false;
          }
       }
       else
       {
          return true;
       }
    }
    else
    {
       return false;
    }
}
document.write(totalNumDays);

https://codepen.io/pen?template=QWmqeqj

步骤:

1). 如果年份能被

100 整除,那么如果年份能被 400 整除。

*The year is a leap year.*

2).如果年份不能被100整除,那么如果年份能被4整除。

*The year is a leap year.*

3).如果年份不能被100整除,年份不能被400整除,或者年份不能被4整除。

*The year is not a leap year.*