Java
java8

いまさら始めるJava8 ~日付時刻API~

前回:続・いまさら始めるJava8 ~StreamAPI~
前々回:いまさら始めるJava8 ~forEachとラムダ式~

Java8で追加された日付時刻API

Java7で日付時刻を扱う場合、値の保持はDateクラス, 操作はCalendarクラスと分かれていましたが、Java8でまとめて扱える API群が追加されました

代表的なクラス

  • LocalDateTime
    タイムゾーンのない日付時刻

  • OffsetDateTime
    UTC/グリニッジからのオフセット付きの日時

  • ZonedDateTime
    タイムゾーン付きの日付/時間

  • Instant
    ある時刻を表す値
    1970-01-01T00:00:00Zからのエポック秒を表すlongと、ナノ秒を表すintを持ちます

特徴

  • 日付時刻の値の保持と操作の両方ができる
  • 時刻をナノ秒までの精度で表せる
  • 不変(Immutable)

使い方

LocalDateTime、OffsetDateTime、ZonedDateTimeの使い方はほぼ一緒なのでLocalDateTimeで説明します

現在時刻の取得

LocalDateTime current = LocalDateTime.now();  // -> 2018-03-03T12:09:50.875

日付時刻を指定して生成

LocalDateTime atMin = LocalDateTime.of(2018,3,3,12,1);                  // -> 2018-03-03T12:01
LocalDateTime atSec = LocalDateTime.of(2018,3,3,12,1,23);               // -> 2018-03-03T12:01:23
LocalDateTime atNanoSec = LocalDateTime.of(2018,3,3,12,1,23,123456789); // -> 2018-03-03T12:01:23.123456789

年月日時分まで、秒まで、ナノ秒まで指定して生成するstaticメソッドが用意されています
指定しなかったフィールドはゼロになります
月はCalendarクラスと異なり1~12で指定できます

Date/Calendarからの変換

Date/CalendarからLocalDateTimeに変換するには新しく追加された.toInstant()メソッドを使いInstantを経由します
ZoneIdの指定が必要なのでシステムデフォルトを取得します

Calendar now = Calendar.getInstance();
Instant nowInstant = now.toInstant();
LocalDateTime fromCalendar = LocalDateTime.ofInstant(nowInstant, ZoneId.systemDefault());

日付時刻の取得

年月日時分秒ナノ秒それぞれを取得するメソッドがあります

LocalDateTime current = LocalDateTime.now(); // -> 2018-03-03T12:09:50.875

System.out.println(current.Hour());          // -> 12
System.out.println(current.getMonth());      // -> MARCH
System.out.println(current.getMonthValue()); // -> 3

getMonth()メソッドは月を表す列挙型Monthを返します

日付時刻の操作

Java7まではCalendarクラスが担当していた操作はLocalDateTimeで直接扱えます
年月日時分秒ナノ秒それぞれに加算(plus)、減算(minus)したLocalDateTimeを返すメソッドが用意されています
元のインスタンスの値は変化しません

LocalDateTime current = LocalDateTime.now();     // -> 2018-03-03T12:09:50.875

LocalDateTime plusMin = current.plusMinutes(10); // -> 2018-03-03T12:19:50.875
LocalDateTime plusMonth = current.plusMonths(2); // -> 2018-05-03T12:09:50.875
LocalDateTime minusYear = current.minusYears(1); // -> 2017-03-03T12:09:50.875

フォーマッタ

日付時刻のフォーマットにはDateTimeFormatterクラスのofPatternメソッドを使います

LocalDateTime current = LocalDateTime.now();
System.out.println(current.format(DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss.SSS"))); // -> 2018/03/03 12:09:50.875

ISOフォーマットで定義された定数を使用することもできます

LocalDateTime current = LocalDateTime.now();
System.out.println(current.format(DateTimeFormatter.ISO_DATE));       // -> 2018-03-03
System.out.println(current.format(DateTimeFormatter.ISO_LOCAL_TIME)); // -> 12:09:50.875