【Java】うるう年判定の最適解。標準API活用と独自ロジックの急所

【Java】うるう年判定の最適解。標準API活用と独自ロジックの急所 Java

Javaで「うるう年」を判定する。
極めて初歩的な課題だが、これすら正確に実装できない自称エンジニアが多すぎる。

条件分岐の優先順位を間違え、バグを垂れ流す。
そんな無様な真似は許されない。

この記事では、Javaにおけるうるう年判定の「正解」を提示する。
曖昧な理解でコードを書くのはやめろ。
定義を脳に刻み込め。

【執筆者の簡易プロフィール】
江田島 執筆者:江田島
  • 43歳男性、既婚、1児の父
  • アプリケーションエンジニア
  • 大手受託開発企業に勤務中
  • Java一筋の職人(教え方はスパルタ気味)
  • 嫌いなもの:やる気のないエンジニア

うるう年の定義を正しく理解せよ

プログラムを書く前に、まずは仕様を完璧に理解するのが鉄則である。
グレゴリオ暦におけるうるう年のルールは以下の3点のみだ。

①西暦年が4で割り切れる年はうるう年とする。
②ただし、100で割り切れる年は平年とする。
③しかし、400で割り切れる年はうるう年とする。

この優先順位を1文字でも違えて実装すれば、それは「ゴミ」と同じである。

特に「100で割り切れるが400で割り切れない年(例:2100年)」をうるう年と判定してしまうミスが後を絶たない。

プロを名乗るなら、こうした境界値を絶対に外すな。

独自ロジックによる判定(if文の実装)

標準APIを使わずにロジックを組む場合、条件式の書き方でエンジニアの素養が問われる。

無駄にネスト(階層)を深くするな。
論理演算子を使い、簡潔に記述しろ。

public class LeapYearChecker {
public static boolean isLeap(int year) {
// 4で割り切れ、かつ(100で割り切れない、または400で割り切れる)
if ((year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)) {
return true;
}
return false;
}

public static void main(String[] args) {
    int year = 2100;
    if (isLeap(year)) {
        System.out.println(year + "年はうるう年である。");
    } else {
        System.out.println(year + "年は平年である。");
    }
}
}

この1行の論理式で完結させるのが、保守性の高いコードである。

「400で割り切れるかどうか」を先に判定してもよいが、いずれにせよ評価の優先順位を間違えないことが絶対条件である。

これが書けないのであれば、今すぐキーボードを置いてエンジニアを廃業しろ。

java.timeパッケージ(Java 8以降)を活用せよ

現代のJavaエンジニアが独自ロジックを自作するのは、アルゴリズムの学習目的以外では時間の無駄である。

Java 8から導入された「Date and Time API(java.timeパッケージ)」には、うるう年判定のためのメソッドが既に用意されている。

Yearクラスによる判定

最も直感的なのは java.time.Year クラスを使用する方法だ。

import java.time.Year;

public class Main {
public static void main(String[] args) {
int yearValue = 2024;

    // YearクラスのisLeapメソッドを使用
    if (Year.isLeap(yearValue)) {
        System.out.println(yearValue + "年はうるう年である。");
    } else {
        System.out.println(yearValue + "年は平年である。");
    }
}
}

LocalDateクラスによる判定

日付情報を既に持っている場合は、LocalDate クラスから判定することも可能だ。

import java.time.LocalDate;

public class Main {
public static void main(String[] args) {
LocalDate now = LocalDate.now();

    // LocalDateから直接判定
    if (now.isLeapYear()) {
        System.out.println("今年はうるう年である。");
    } else {
        System.out.println("今年は平年である。");
    }
}
}

自作のロジックには常にバグが混入するリスクがあるが、標準ライブラリはテストし尽くされている。

特別な理由がない限り、標準機能を使え。それが「車輪の再発明」を防ぐプロの立ち振る舞いである。

旧時代の遺物(Calendarクラス)は使うな

いまだに java.util.Calendarjava.util.GregorianCalendar を使って判定しようとする者がいる。

// このような古い書き方は推奨されない
GregorianCalendar cal = new GregorianCalendar();
boolean result = cal.isLeapYear(2024);

Calendarクラスは設計が古く、ミュータブル(可変)であるためスレッドセーフではない。

モダンなJava開発において、これらのクラスを持ち込むのは「負債」を増やす行為に他ならない。

現場のコーディング規約に古いクラスが残っているなら、率先して駆逐しろ。

まとめ:エンジニアなら仕様を「断言」できるコードを書け

うるう年判定ひとつ取っても、エンジニアの質は透けて見える。
「なんとなく動く」コードではなく、「仕様に基づき、誰が見ても正しいと断言できる」コードを書け。

定義(4, 100, 400のルール)を完璧に理解する。
独自実装なら、簡潔な論理演算で記述する。
実務なら、java.time.Year を迷わず選択する。

基本を疎かにする奴に、大規模なシステム開発など到底無理だ。

以上である。

コメント

タイトルとURLをコピーしました