首页 文章

javascript找到闰年

提问于
浏览
19

如果我有一个月的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 +'/' +  '';
    }
}

7 回答

  • 11

    Date objects用于日期时间的东西更安全,例如

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

    由于人们不断询问这是如何工作的,因此它与JS如何计算年 - 月 - 日的日期值有关(详情here) . 基本上,它首先计算该月的第一天,然后为其添加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月28日= 2月29日:

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

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

  • 5

    Compared to using new Date() this is is around 100 times faster!

    Update:

    这个最新版本使用了底部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
    
  • 2

    Correct and Fast:

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

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

  • 6
    isLeap = !(new Date(year, 1, 29).getMonth()-1)
    

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

  • 1

    更好的历史计算闰年 .

    下面的代码考虑到侏儒在公元前45年引入了朱利安历法,并且大多数西方世界在1582CE采用公历,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年采用了公历,所以如果你更加以盎格鲁为中心,这个版本更好(我们假设英国采用朱利安历法,罗马征服从43CE开始) .

    isLeap = function(yr) {
      if (yr > 1752) return !((yr % 4) || (!(yr % 100) && (yr % 400)));
      if (yr >= 43) return !(yr % 4);
      return false;
    };
    
  • 1

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

    var year = 2012;
    var isLeap = new Date(year,2,1,-1).getDate()==29;
    
  • 103

    您可以轻松地将此工作从momentjs调用.isLeapYear()

    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>
    

相关问题