【Java進化史 第24回】Java8で日付APIは何がどう変わったのか 〜 DateとCalendarからの卒業 〜
風の噂で聞いた。
Java8で、日付系のAPIが変わったらしい。
「また何か増えたのか?」
正直、最初はその程度の認識だった。
だが調べてみると、これは単なる追加ではない。
DateとCalendarからの、事実上の世代交代だった。
■ なぜ変更されたのか(軽く)
Java7以前、日付といえばこれだった。
java.util.Date
java.util.Calendar
java.text.SimpleDateFormat
動く。
だが、扱いづらい。
- DateやCalendarはmutable(変更可能)
- SimpleDateFormatはスレッドセーフではない
- 月が0始まりなど、直感的でない仕様
そこでJava8で追加されたのが、
java.time パッケージである。
■ 何がどう変わったのか
① 現在日時の取得
Java7
Date now = new Date();
Java8
LocalDateTime now = LocalDateTime.now();
何が変わったか。
Dateは「日付と時刻の塊」だった。
LocalDateTimeは「日付+時刻」という意味が明確である。
② 日付だけ取得
Java7
Calendar cal = Calendar.getInstance();
int year = cal.get(Calendar.YEAR);
Java8
LocalDate today = LocalDate.now();
int year = today.getYear();
フィールド定数が不要になった。
読みやすさが違う。
③ 日付加算
Java7
Calendar cal = Calendar.getInstance();
cal.add(Calendar.DAY_OF_MONTH, 3);
Java8
LocalDate result = LocalDate.now().plusDays(3);
plusDays。
何をしているかが、そのまま読める。
④ フォーマット
Java7
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
String str = sdf.format(new Date());
※ SimpleDateFormatはスレッドセーフではない。
Java8
DateTimeFormatter formatter =
DateTimeFormatter.ofPattern("yyyy-MM-dd");
String str = LocalDate.now().format(formatter);
DateTimeFormatterは不変(immutable)。
安全に使える。
⑤ 文字列から日付へ
Java7
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
Date date = sdf.parse("2026-02-22");
Java8
LocalDate date = LocalDate.parse("2026-02-22");
APIが自然になった。
⑥ 日付の差分
Java7
long diff = date2.getTime() - date1.getTime();
long days = diff / (1000 * 60 * 60 * 24);
ミリ秒計算を自分でやる必要があった。
Java8
long days = ChronoUnit.DAYS.between(date1, date2);
意図が明確になった。
⑦ タイムゾーン
Java7
TimeZone tz = TimeZone.getTimeZone("Asia/Tokyo");
Calendar cal = Calendar.getInstance(tz);
Java8
ZonedDateTime now =
ZonedDateTime.now(ZoneId.of("Asia/Tokyo"));
日付・時刻・タイムゾーンが一体として扱える。
■ 結局、何が変わったのか
- mutable → immutable
- 曖昧 → 役割分離
- 計算ベース → 意味ベースAPI
書きやすくなった。
それだけではない。
バグが入りにくくなった。
地味に見える。
だが実務では、かなり大きい進化だ。