Javaで「うるう年」を判定する。
極めて初歩的な課題だが、これすら正確に実装できない自称エンジニアが多すぎる。
条件分岐の優先順位を間違え、バグを垂れ流す。
そんな無様な真似は許されない。
この記事では、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.Calendar や java.util.GregorianCalendar を使って判定しようとする者がいる。
// このような古い書き方は推奨されない
GregorianCalendar cal = new GregorianCalendar();
boolean result = cal.isLeapYear(2024);
Calendarクラスは設計が古く、ミュータブル(可変)であるためスレッドセーフではない。
モダンなJava開発において、これらのクラスを持ち込むのは「負債」を増やす行為に他ならない。
現場のコーディング規約に古いクラスが残っているなら、率先して駆逐しろ。
まとめ:エンジニアなら仕様を「断言」できるコードを書け
うるう年判定ひとつ取っても、エンジニアの質は透けて見える。
「なんとなく動く」コードではなく、「仕様に基づき、誰が見ても正しいと断言できる」コードを書け。
定義(4, 100, 400のルール)を完璧に理解する。
独自実装なら、簡潔な論理演算で記述する。
実務なら、java.time.Year を迷わず選択する。
基本を疎かにする奴に、大規模なシステム開発など到底無理だ。
以上である。



コメント