web-dev-qa-db-ja.com

うるう年を見つけるためのjavascript

2月が1か月あるときに、以下のコードを機能させるにはどうすればよいですか?現在、うるう年であるかどうかを判断するために、その日まで到達してから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 +'/' +  '';
    }
}
21
Juan Almonte

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 = 29日:

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

上記のコードでは、日付を2月29日に設定し、ロールオーバーが発生したかどうかを確認しています。そうでない場合(月がまだ1、つまり2月)、これはうるう年であり、それ以外の場合はうるう年ではありません。

110
georg

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
16
Gone Coding
isLeap = !(new Date(year, 1, 29).getMonth()-1)

... 1による減算は、ほとんどのCPUアーキテクチャで比較するよりもさらに速く機能します。

6
bofs

正確で速い:

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

ループに入っているか、ナノ秒をカウントしている場合、これは、新しいDate()オブジェクトで1年を実行するよりも2桁速くなります。ここでパフォーマンスを比較してください: http://jsperf.com/ily

6
broc.seib

うるう年のより良い歴史的計算。

以下のコードは、うるう年がユリウス暦で45BCに導入されたこと、および西側世界の大部分が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;
};
2
spirographer

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>
1
guijob

1月を0として、2月を1として参照し続ける必要がないので、これを使用します。私にとって、PHPと読み取り可能な日付、2月= 2です。数は決して変化しませんが、それは私のコードを別のコードで同じように考えさせるだけです。

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

疑似コード

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 )
}

上記のコードを使用すると、yearが4で割り切れない場合、yearごとに1つのチェックのみが実行されます。ブラケットを追加するだけで、割り切れないyearごとに2つのチェックを保存できます。 4

0
Daut

別の方法は、その年の日付が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
0
Robert Todar