1行で書けるうるう年判別法

ある年がうるう年(閏年)であるかどうかの判別は意外と複雑です。

  • 西暦が4で割り切れる年はうるう年
  • ただし、4で割り切れても100で割り切れる年はうるう年でない
  • ただし、100で割り切れても400で割り切れる年はうるう年

つまり、2004年、2008年、…、2096年はうるう年ですが、2100年は100で割り切れるためうるう年でありません(かわいそうなことに、2月29日生まれの人は、2096年から2104年まで、8年間も誕生日がやって来ないわけですね)。しかし、2000年はさらに400で割り切れるのでうるう年となります。

単純な判別

うるう年を単純に判別しようとすると、西暦を格納したyという変数があるとして、2月の日数を表す変数nに28か29を代入するには、

if(y % 4 == 0){
	if(y % 100 == 0){
		if(y % 400 == 0){
			n = 29;
		}else{
			n = 28;
		}
	}else{
		n = 29;
	}
}else{
	n = 28;
}

と、やや煩雑な条件分岐を書かなければなりません(%は余りを求める演算子。a % bはaをbで割った余り)。

1行での判別

上記のような条件判別をしなくても、1行でnを求めてしまう計算式をご紹介しましょう。

n = 28 + (1 / (y % 4 + 1)) * (1 - 1 / (y % 100 + 1)) + (1 / (y % 400 + 1));

これは、整数の割り算が割り切れない場合、切り捨てられることを利用しています。

1 / (y % 4 + 1)

はyが4の倍数の場合のみ1になりますよね。これを組み合わせて上の式になります。

四則演算のみでの判別

さらに、a % bはa - a / b * bで表せるという性質を使って、四則演算だけで上記の式を書き換えてみます。

n = 28 + (1 / (y - y / 4 * 4 + 1)) * (1 - 1 / (y - y / 100 * 100 + 1))
	+ (1 / (y - y / 400 * 400 + 1));

結論

2月の日数は条件分岐を使わなくても、上記のような計算式で簡単に求めることができます。