Java 8以降では、新しい日付・時刻API(java.time パッケージ)が導入され、LocalDate や LocalDateTime を使った実装が推奨されています。
しかし、既存システムやレガシーコードでは Calendar クラス が今も多く使われており、
-
Calendar → LocalDate に変換したい
-
新旧APIを混在させる必要がある
といった場面に遭遇することは少なくありません。
この記事では、CalendarをLocalDateに変換する正しい方法を、注意点と実装例付きでわかりやすく解説します。
CalendarとLocalDateの違い
まずは簡単に違いを整理しておきましょう。
| 項目 | Calendar | LocalDate |
|---|---|---|
| 導入時期 | Java 1.1 | Java 8 |
| ミュータブル | 変更可能 | 不変(イミュータブル) |
| タイムゾーン | 常に保持 | 持たない |
| 推奨度 | 非推奨(レガシー) | 推奨 |
現在は LocalDate / LocalDateTime の利用が推奨されていますが、
既存処理との兼ね合いで Calendar を扱う必要があるケースも多いのが実情です。
CalendarをLocalDateに変換する基本的な方法
基本パターン(推奨)
処理の流れ
-
Calendar→Instantに変換 -
InstantにZoneIdを適用 -
LocalDateに変換
この方法が 最も安全で推奨される変換方法です。
なぜZoneIdが必要なのか?
LocalDate 自体は タイムゾーンを持たない日付クラスです。
一方、Calendar は内部的にタイムゾーンを保持しています。
そのため、
のような直接変換はできません。
必ず以下のように ZoneId を明示する必要があります。
ZoneIdを指定する例
システムデフォルトのタイムゾーンを使う場合
日本時間(Asia/Tokyo)を明示する場合
👉 業務システムでは ZoneId を明示指定する方が安全です。
よくある間違い(注意点)
❌ Calendarの年月をそのまま使う
Calendar.MONTH は 0始まり(1月=0) のため、
この方法は 月ズレのバグを引き起こします。
❌ Date経由で雑に変換する
動作はしますが、Calendar → Date → Instant と経由が増えるため、
可読性・保守性の観点でおすすめできません。
LocalDateに変換すべき理由
CalendarからLocalDateへ変換することで、以下のメリットがあります。
-
イミュータブルで安全
-
APIが直感的で読みやすい
-
日付計算(加算・減算)が簡単
-
Java公式が推奨している
まとめ
-
Java 8以降では
LocalDateの利用が推奨 -
Calendar → LocalDate の変換は Instant + ZoneId を経由
-
ZoneIdの指定を忘れない -
Calendar.MONTHの罠に注意
