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)

うるう年の場合、1 日 + 28 = 2 月 29 日:

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

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

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

...1 の減算は、ほとんどの CPU アーキテクチャでの比較よりもさらに高速に動作するはずです。

于 2013-04-01T16:41:03.687 に答える
6

正確かつ迅速:

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

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

于 2013-06-14T20:12:08.000 に答える
2

うるう年の履歴計算が改善されました。

以下のコードは、閏年がユリウス暦で 45BC に導入されたこと、西暦 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 年にグレゴリオ暦を採用したため、より英国中心の場合は、このバージョンの方が適しています (英国は 43CE に始まるローマの征服でユリウス暦を採用したと仮定します)。

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

1 月を 0、2 月を 1 と呼び続けるのが嫌なので、これを使用します。私と PHP と読み取り可能な日付にとって、2 月 = 2 です。数字は決して変わらないので、実際には問題ではないことはわかっていますが、異なるコードで脳が同じように考え続けるだけです。

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