JavaのDateとCalendarと新しい日付APIの違いとは?初心者向け完全ガイド
生徒
「Javaで日付や時間を扱うときって、DateクラスとかCalendarクラスとか、いろいろあって混乱します……。結局どれを使えばいいんですか?」
先生
「たしかにJavaには複数の日付・時間APIがありますね。DateやCalendarは古い日付クラス、新しいものはJava 8で導入されたjava.timeパッケージのクラスです。」
生徒
「それぞれ何が違って、どっちを使えば良いのか分からないです……。」
先生
「それでは、JavaのDateやCalendarと、新しいLocalDateやLocalDateTimeの違いを詳しく解説していきましょう!」
1. Javaの日付・時間APIは2種類ある
Javaでは、日付や時間を扱うために次の2種類のAPIがあります。
- 旧API:
java.util.Date、java.util.Calendar、java.text.SimpleDateFormatなど - 新API:
java.time.LocalDate、LocalDateTime、ZonedDateTime、DateTimeFormatterなど
旧APIはJava初期から存在しますが、設計に問題が多く、保守性や可読性に欠けていました。そのため、Java 8で新しい日付・時間APIが導入され、今では新APIの使用が推奨されています。
2. DateとCalendarの主な問題点
Javaの旧APIであるDateとCalendarには、以下のような問題があります。
- 可読性が低い:使い方が直感的でなく、コードが分かりにくくなる
- 不変ではない:インスタンスの内容が変更可能なため、バグの温床になる
- 月が0始まり:
Calendarでは1月が0、12月が11という仕様で混乱しやすい - スレッドセーフでない:
SimpleDateFormatなどはマルチスレッドで正しく動作しない
3. 新しい日付API(java.timeパッケージ)の特徴
Java 8から導入されたjava.timeパッケージは、旧APIの課題を解決するモダンな日付・時間APIです。以下のような利点があります。
- 不変(Immutable):インスタンスが変更不可で安全
- 明確な設計:
LocalDate(日付)、LocalTime(時間)、LocalDateTime(日付+時間)など役割が分かれている - 日時の比較や加算が簡単:
plusDays()やisBefore()など便利なメソッドが揃っている - スレッドセーフ:マルチスレッド環境でも安心して使用可能
- タイムゾーン対応:
ZonedDateTimeでタイムゾーンを意識した日時が扱える
4. DateとLocalDateの比較:基本の使い方
旧APIのDateと、新APIのLocalDateを比較してみましょう。
旧API(Date)を使う例:
import java.util.Date;
public class OldDateExample {
public static void main(String[] args) {
Date now = new Date();
System.out.println("現在日時(Date): " + now);
}
}
新API(LocalDate)を使う例:
import java.time.LocalDate;
public class NewDateExample {
public static void main(String[] args) {
LocalDate today = LocalDate.now();
System.out.println("今日の日付(LocalDate): " + today);
}
}
5. LocalDateTimeで日時を扱う方法
LocalDateTimeを使えば、日付と時間の両方を簡単に扱えます。
import java.time.LocalDateTime;
public class LocalDateTimeExample {
public static void main(String[] args) {
LocalDateTime now = LocalDateTime.now();
System.out.println("現在日時(LocalDateTime): " + now);
}
}
このように新しい日付APIを使えば、コードがシンプルでわかりやすくなります。
6. 書式設定の違い:SimpleDateFormat vs DateTimeFormatter
SimpleDateFormatは旧APIの代表的なフォーマッタですが、スレッドセーフでない欠点があります。
旧API:
import java.text.SimpleDateFormat;
import java.util.Date;
public class OldFormatExample {
public static void main(String[] args) {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd");
String formatted = formatter.format(new Date());
System.out.println("フォーマット結果(旧API): " + formatted);
}
}
新API:
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
public class NewFormatExample {
public static void main(String[] args) {
LocalDate today = LocalDate.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy/MM/dd");
String formatted = today.format(formatter);
System.out.println("フォーマット結果(新API): " + formatted);
}
}
7. よく使う新しい日付クラスまとめ
以下はJavaの新しい日付・時間APIでよく使う代表的なクラスです。
LocalDate:日付のみLocalTime:時間のみLocalDateTime:日付+時間ZonedDateTime:タイムゾーン付きの日時Instant:UTC(協定世界時)での瞬間PeriodやDuration:期間や時間の長さを扱う
8. DateやCalendarは使ってはいけないの?
DateやCalendarは古いライブラリと連携するときや、どうしても必要なときには使いますが、基本的にはjava.timeパッケージを優先しましょう。今後の開発では新APIが標準です。
どうしてもDateとLocalDateの変換が必要なときは、java.sqlやInstant経由で変換可能です。