28

当我有一个月的 2 月时,如何让下面的代码工作?目前它正在到达当天,然后在到达 if 之前停止,以确定它是否是闰年。

 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 +'/' +  '';
    }
}
4

13 回答 13

123

将Date 对象用于日期时间的东西会更安全,例如

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

由于人们一直在问这到底是如何工作的,这与 JS 如何从年月日计算日期值有关(详情请参阅此处)。基本上,它首先计算一个月的第一天,然后将 N -1 天添加到它。因此,当我们要求非闰年的 2 月 29 日时,结果将是 2 月 1 日 + 28 天 = 3 月 1 日:

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

在闰年,2 月 1 日 + 28 = 2 月 29 日:

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

在上面的代码中,我将日期设置为 2 月 29 日,并查看是否发生了翻转。如果不是(月份仍为 1,即二月),则为闰年,否则为非闰年。

于 2011-11-17T23:35:47.217 回答
18

与使用new Date()它相比,它快了大约 100 倍!

更新:

这个最新版本使用了底部 3 位的位测试(它是 4 的倍数),以及检查年份是 16 的倍数(二进制的底部 4 位是 15)和 25 的倍数。

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

http://jsperf.com/ily/15

它比我以前的版本(下)稍微快一点:

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

http://jsperf.com/ily/7

与 broc.seib 已经快速的条件运算符版本相比,它也快了 5%

速度测试结果:http: //jsperf.com/ily/6

预期的逻辑测试结果:

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
于 2013-10-24T16:03:38.177 回答
6
isLeap = !(new Date(year, 1, 29).getMonth()-1)

...在大多数 CPU 架构上,减一应该比比较更快。

于 2013-04-01T16:41:03.687 回答
6

正确和快速:

ily = function(yr) { return (yr%400)?((yr%100)?((yr%4)?false:true):false):true; }

如果您处于循环中或计算纳秒,这比通过新的 Date() 对象运行您的年份快两个数量级。在此处比较性能:http: //jsperf.com/ily

于 2013-06-14T20:12:08.000 回答
2

更好的闰年历史计算。

下面的代码考虑到闰年是在公元前 45 年与儒略历一起引入的,而西方世界的大多数人在公元 1582 年采用了格里高利历,并且 0CE = 1BC。

isLeap = function(yr) {
  if (yr > 1582) return !((yr % 4) || (!(yr % 100) && (yr % 400)));
  if (yr >= 0) return !(yr % 4);
  if (yr >= -45) return !((yr + 1) % 4);
  return false;
};

英国及其殖民地在 1752 年采用了公历,所以如果你更以盎格鲁为中心,这个版本会更好(我们假设英国从公元 43 年开始采用儒略历和罗马征服)。

isLeap = function(yr) {
  if (yr > 1752) return !((yr % 4) || (!(yr % 100) && (yr % 400)));
  if (yr >= 43) return !(yr % 4);
  return false;
};
于 2015-10-02T02:51:20.797 回答
1

我之所以使用它,是因为我讨厌不得不一直将一月称为 0,二月称为 1。对我和 PHP 和可读日期而言,二月 = 2。我知道这并不重要,因为数字永远不会改变,但它只是让我的大脑在不同的代码中思考相同。

var year = 2012;
var isLeap = new Date(year,2,1,-1).getDate()==29;
于 2013-08-09T14:47:27.210 回答
1

您可以轻松地.isLeapYear()从以下位置调用它momentjs

var notLeapYear = moment('2018-02-29')
console.log(notLeapYear.isLeapYear()); // false

var leapYear = moment('2020-02-29')
console.log(leapYear.isLeapYear()); // true
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.21.0/moment.min.js"></script>

于 2018-03-06T05:19:33.467 回答
1
function isLeap(year) {   
    if ( (year % 4 === 0 && year % 100 !== 0) || (year % 4 === 0 && year % 100 === 0 && year % 400 === 0) ) {
        return 'Leap year.'
    } else {
        return 'Not leap year.';
    }
}
于 2021-01-05T05:48:53.890 回答
1

都在一条线上

const isLeapYear = (year) => (year % 100 === 0 ? year % 400 === 0 : year % 4 === 0);

console.log(isLeapYear(2016)); // true
console.log(isLeapYear(2000)); // true
console.log(isLeapYear(1700)); // false
console.log(isLeapYear(1800)); // false
console.log(isLeapYear(2020)); // true
于 2020-07-05T22:05:12.333 回答
0

另一种选择是查看那一年是否有2 月 29 日这一日期。如果确实有这个日期,那么您就知道这是闰年。

ES6

// Months are zero-based integers between 0 and 11, where Febuary = 1
const isLeapYear = year => new Date(year, 1, 29).getDate() === 29;

测试

> isLeapYear(2016);
< true
> isLeapYear(2019);
< false
于 2019-09-04T18:30:12.950 回答
0

Pseudo code

if year is not divisible by 4 then not leap year
else if year is not divisible by 100 then leap year
else if year is divisible by 400 then leap year
else not leap year

JavaScript

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

Using the above code insures you do only one check per year if the year is not divisible by 4 Just by adding the brackets you save 2 checks per year that is not divisible by 4

于 2019-02-04T14:33:22.953 回答
0
function leapYear(year){
    if((year%4==0) && (year%100 !==0) || (year%400==0)){
        return true;
    }
    else{
        return false;
    }
}
var result = leapYear(1700);
console.log(result);
于 2021-01-19T10:06:26.677 回答
0

预计 JavaScript 将获得一个新的日期/时间 API,它公开一个新的全局对象 - Temporal. 这个全局对象为 JS 开发者提供了一种更好的方式来处理日期/时间。它目前是第 3 阶段的提案,有望很快投入使用。

temporal api 公开了一个很好的属性来检查闰年 - inLeapYear. true如果特定日期是闰年,则返回,否则返回false。下面我们with()用于将返回的日期转换为plainDateISO我们特定年份的日期:

const isLeap = year => Temporal.now.plainDateISO().with({year}).inLeapYear;
console.log(isLeap(2020)); // true
console.log(isLeap(2000)); // true
console.log(isLeap(1944)); // true

console.log(isLeap(2021)); // false
console.log(isLeap(1999)); // false

如果您只想检查您当前的系统日期时间是否是闰年,您可以省略.with()

// true if this year is a leap year, false if it's not a leap year
const isLeap = Temporal.now.plainDateISO().inLeapYear; 
于 2021-06-25T12:24:16.910 回答