アルゴリズム

閏年の判定アルゴリズム

閏年の定義

グレゴリオ暦法では、次の規則に従って400年間に97回の閏年を設けています。

① 西暦年が4で割り切れる年は(原則として)閏年。
② ただし、西暦年が100で割り切れる年は(原則として)平年。
③ ただし、西暦年が400で割り切れる年は必ず閏年。

この置閏法(閏の挿入規則)によるただし書きをひとことで表すと、「400年に3回、100で割り切れるが400で割り切れない年は、例外で平年とする」ということになります。
これをプログラミング言語で、どのように表現するのが正しいのでしょうか。

閏年の判定アルゴリズム

グレゴリオ暦の閏年は、次のどちらかの判定ロジックで、正しく判定することができます。

計算式①:逐次的な4条件

プログラムで処理しやすくするために、閏年の規則を、次の4条件に読み替える計算方法です。

① 西暦年が400の倍数である場合、閏年
② 条件①を満たさず(西暦年が400の倍数ではなく)、かつ西暦年が100の倍数である場合、平年
③ 条件①と②を両方とも満たさず(西暦年が100の倍数ではなく)、かつ西暦年が4の倍数である場合、閏年
④ 条件①〜③を全て満たさない場合、平年

プログラム言語では、以下のように記述できます。
※注:コーディング例だと、結果が確定した時点でリターンしているため、ELSE内の入れ子を省略する書き方も可能です。コードがもっと短くできますね。

  • C言語など
  • Visual Basicなど
// C言語など
int year = 西暦;
if (year % 400 == 0) {
    return true;
} else {
    if (year % 100 == 0) {
        return false;
    } else {
        if (year % 4 == 0) {
            return true;
        } else {
            return false;
        }
    }
}
' Visual Basicなど
Dim year As Integer = 西暦
If year Mod 400 = 0 Then
    Return True
Else
    If year Mod 100 = 0 Then
        Return False
    Else
        If year Mod 4 = 0 Then
            Return True
        Else
            Return False
        End If
    End If
End If

計算式②:1つの論理式

閏年の規則を、次の1つだけの論理式に読み替える計算方法です。

① 西暦年が、「4の倍数である」かつ「100の倍数でない」または「400の倍数である」ならば閏年、そうでなければ平年

この条件は、
①『「4の倍数である」かつ「100の倍数でない」』または「400の倍数である」
②「4の倍数である」かつ『「100の倍数でない」または「400の倍数である」』
の2通りの解釈ができますが、どちらの解釈でも同じ結果となります(「400の倍数である」=「4の倍数である」が成り立つため)。

プログラム言語では、以下のように記述できます。
※注:論理演算子が文字化けするため、当サイトではこの記法を採用しません。が、ひとつの論理式で簡潔にロジックを表現できるため、言語仕様上の制約がなければ、この書き方をするのが一般的かなと思います。

  • C言語など
  • Visual Basicなど
// C言語など
int year = 西暦;
if (year % 4 == 0 && year % 100 != 0 || year % 400 == 0) {
    return true;
} else {
    return false;
}
' Visual Basicなど
Dim year As Integer = 西暦
If year Mod 4 = 0 And year Mod 100 <> 0 Or year Mod 400 = 0 Then
    Return True
Else
    Return False
End If

うるう年の確かめ算

西暦を入力すると、①4の倍数か(4で割り切れるか)、②100の倍数か(100で割り切れるか)、③400の倍数か(400で割り切れるか)、をチェックし、うるう年か平年か判定します。

4の倍数
100の倍数
400の倍数
判定閏年

ソースコード公開

<form>
<label for="year">西暦<input type="number" id="year" oninput="calc()">年</label>
</form>
<script>
// 計算
function calc() {
  let year = document.getElementById('year').value;
  let tds = document.getElementsByTagName('td');
  // 初期値クリア
  for (let i = 1; i < tds.length; i = i + 2) {
    tds[i].innerText = '';
  }
  // 4の倍数
  if (year % 4 == 0) {
    tds[1].innerText = '○';
  }
  // 100の倍数
  if (year % 100 == 0) {
    tds[3].innerText = '○';
  }
  // 400の倍数
  if (year % 400 == 0) {
    tds[5].innerText = '○';
  }
  // 閏年判定
  let result = '平年';
  if (year % 400 == 0) {
    result = '閏年';
  } else if (year % 100 != 0) {
    if (year % 4 == 0) {
      result = '閏年';
    }
  }
  tds[7].innerText = result;
}
</script>



コメント