javascript 查找闰年

IT技术 javascript date textfield leap-year
2021-01-19 02:30:29

当我有一个月的二月时,我怎样才能让下面的代码工作?目前它正在进入这一天,然后在进入 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 +'/' +  '';
    }
}
6个回答

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)

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

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

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

这在 IE11 上不起作用,因为在结果Date()对象中通过 29th 获得更正为 2 月 28 日因此返回 1 并错误地标记为闰年。
2021-03-15 02:30:29
@RymanHolmes JavaScriptDate对象中的月份是零索引的。在闰年,第 1 个月(二月)的第 29 天有效,因此getMonth()返回1(二月)。在非闰年,JavaScript 将 2 月 29 日“更正”为 3 月 1 日,因此getMonth()将返回2(三月)。
2021-03-27 02:30:29
天啊。什么黑客。:)
2021-04-09 02:30:29
仅用于低容量场景,因为这比使用诸如jsperf.com/ily/7 之类的东西慢 100 倍isLeap = !((yr % 4) || (!(yr % 100) && (yr % 400))); 左右
2021-04-09 02:30:29
== 1这里做什么?
2021-04-13 02:30:29

与使用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
isLeap = !(new Date(year, 1, 29).getMonth()-1)

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

如果你被要求每秒计算 1000 个这些,我可能会同意,但是当它们之间的速度差异几乎可以忽略不计时,可读性应该胜过速度。
2021-03-25 02:30:29
刚刚进行了一些速度测试,new Date比使用布尔逻辑慢了大约 100 倍(比如!((yr % 4) || (!(yr % 100) && (yr % 400))))。你可以说,为了速度,我现在已经把可读性抛到了窗外,但 100 次可能是值得的:)
2021-04-02 02:30:29

正确和快速:

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

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

你现在知道什么是否定了吗?
2021-03-19 02:30:29
由于这只是将布尔比较与布尔结果相结合,因此您可以在没有条件运算符的情况下表达这一点,而只需使用 && 、 || 和短路。速度也快了大约 5%:jsperf.com/ily/6
2021-04-05 02:30:29

更好的闰年历史计算。

下面的代码考虑到闰年是在公元前 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;
};
+ 历史课。现在的问题是:闰年不是追溯性引入的吗?
2021-04-02 02:30:29