エンジニアなら知ってる?「うるう年」のこと

一年は365日が基本ですが、うるう年の年だけ、366日になる。ということは誰でも知っていることだと思います。
ほかに4年に1度訪れることは一般常識ですね。
しかし、実はうるう年は4年に1度ではないのです。このことをエンジニアのみなさんならご存知の方も多いのではないでしょうか?

うるう年の条件

うるう年は4年に1度訪れる……というのは間違いないのですが、実は条件があり、西暦での年が100で割り切れる場合はうるう年ではなくなるのです。
最近で100で割り切れる年といえば、2000年。では、2000年がうるう年ではなかったと記憶している方はいるでしょうか?
もし記憶している方がいれば、それは誤りです。
さらに条件は複雑で、西暦での年が400で割り切れる場合はうるう年となります。
少しごちゃごちゃしてきたので整理します。

① 西暦が4で割り切れる年はうるう年
② ただし、100で割り切れる年はうるう年ではない
③ ただし、400で割り切れる年はうるう年

よって2000年は③、400で割り切れる年、に当てはまるので、うるう年となります。

先でエンジニアなら知っている人も多いのでは?と書きましたが、これは条件分岐、いわゆるif文、の学習をするときの例題として頻繁に使われるからです。
今回はうるう年を題材に、条件を整理するポイントをご紹介します。

実際にコードとして考えてみる

うるう年の条件をコードで考えてみましょう。
筆者が上の例題を初めて問いた際、C言語を使用したので、C言語っぽく先程の条件を記述すると以下のような感じでしょうか。

cpp
if (year % 4 == 0)
{
	if (year % 100 == 0)
	{
		if (year % 400 == 0)
		{
			// yearが4で割り切れる。かつ、100で割り切れる。かつ400で割り切れる。
			printf("うるう年");
		}
		else
		{
			// yearが4で割り切れる。かつ、100で割り切れる。かつ400で割り切れない。
			printf("うるう年ではない");
		}
	}
	else
	{
		// yearが4で割り切れる。かつ、100で割り切れない。
		printf("うるう年")
	}
}
else
{
	// yearが4で割り切れない
	printf("うるう年ではない")
}

上のような記述は条件をそのまま愚直に実装した際のコードです。
コメントがあるから理解できるものの、ネストが深くなりすぎて少し嫌な感じがしませんか?

下記のように、条件を整理してみると、ネストが浅く、スッキリしたコードになります。

① 400で割り切れる年はうるう年
② ①を満たさない場合、100で割り切れる年はうるう年ではない
③ ①②を満たさない場合、4で割り切れる年はうるう年
④ ①②③を満たさない場合、うるう年ではない

cpp
if (year % 400 == 0)
{
	// yearが400で割り切れる。
	printf("うるう年");
}
else if (year % 100 == 0)
{
	// yearが400で割り切れない、かつ、100で割り切れる。
	printf("うるう年ではない");
}
else if (year % 4 == 0)
{
	// yearが400で割り切れない、かつ、100で割り切れない、かつ、4で割り切れる。
	printf("うるう年");
}
else
{
	// yearが400で割り切れない、かつ、100で割り切れない、かつ、4で割り切れない。
	printf("うるう年ではない");
}

条件を整理しよう

今回はうるう年の話を交えつつ、条件に関する話をしました。コードを書くうえでさまざまな条件が降り注いできますが、コードを書く前にそれを上手く整理してあげると、スッキリしたコードを書けることはよくあります。
条件を整理することを意識して、少しでも綺麗なコードを目指してみましょう。

[文]ペンネーム:酢醤油 [編集]サムライト編集部