新たな日付処理のためのAPI

これまでJavaでの日時処理にはjava.util.Calendarやjava.util.Dateが使われてきた。これらのAPIは設計も古く、決して使い勝手のよいものではなく、また国際化関連の機能が不十分といった欠点もあった。Java 8ではこれらのAPIを置き換えるためのものとして新たにJava Time APIとしてjava.timeパッケージが導入された。

Time APIでは日時を表すための型として以下のようなクラスが用意されている。

  • LocalDate … タイムゾーンを持たない日付
  • LocalDateTime … タイムゾーンを持たない日時
  • LocalTime … タイムゾーンを持たない時刻
  • OffsetDateTime … UTCからの時差を持つ日時
  • OffsetTime … UTCからの時差を持つ時刻
  • ZonedDateTime … タイムゾーンを持つ日時
  • Duration … 時間の量
  • Period … 日付の量

日付や時刻を表すクラスはnow()メソッドで現在日時を表すインスタンスを取得することができる。また、コンストラクタで日時を指定してインスタンスを生成することも可能だ。

// 現在日時を取得
LocalDateTime localDateTime = LocalDateTime.now();
// 現在日を生成
LocalDate localDate = LocalDate.now();
// 現在時刻を生成
LocalTime localTime = LocalTime.now();
// 年月日時分まで指定して生成
LocalDateTime localDateTime = LocalDateTime.of(2014, 07, 12, 12, 5);

このようにして生成した日時オブジェクトに対してメソッドチェーンで日時の計算を行うことができる。

LocalDateTime dateTime = LocalDateTime.now();

// 2年6ヶ月後の日付を取得
LocalDateTime result1 = dateTime.plusYears(2).plusMonths(6);
// 2週間前の日付を取得
LocalDateTime result2 = dateTime.minusWeeks(2);

もちろんTime APIの日時オブジェクトとDateオブジェクトを相互に変換する方法も用意されており、既存のjava.util.Dateベースのライブラリやフレームワークとの相互運用性も可能だ。

// java.util.DateをTime APIの日時に変換
Date nowDate = new Date();
Instant instant = nowDate.toInstant();
ZonedDateTime zonedDateTime = ZonedDateTime.ofInstant(instant, ZoneId.of("Asia/Tokyo"));

// Time APIの日時をjava.util.Dateに変換
ZonedDateTime now = ZonedDateTime.now();
Instant instantNow = Instant.from(now);
Date dateNow = Date.from(instantNow);

このように、とりわけ日時の計算処理については従来のCalendarやDateを使用した場合との違いは一目瞭然で、Time APIでは非常に簡潔に記述できる。Java 8では積極的にTime APIを活用するようにしたい。