ふみぽん's diary

技術的な備忘録が主のブログ

Java実践 TimeAPI (Java8)

TimeAPIについての備忘録


TimeAPI

Java8から日付関連のクラス群がjava.timeパッケージをして追加になった。  

Date,Calendarと比較すると、

  • APIがわかりやすい
  • 並行処理をしても日時情報を持つインスタンスの中身が壊れないような設計になっている

java.timeパッケージの代表的なクラス

1. Instantクラス

  • エポックからの経過時間をナノ秒数で格納する。
  • 旧来のAPIにおけるDateクラスと同じような役割。
  • ナノ秒単位で正確に瞬間を表すことができる。
//InstantはDateと同じように内部的にはlong型の情報を持つ
//Instantの生成 現在日時の取得
Instant i1 = Instant.now();

System.out.println(i1);    // =>2019-05-18T07:36:27.579Z


//Instantとlongの相互変換
Instant i2 = Instant.ofEpochMilli(31920291332L);

long l2 = i2.toEpochMilli();

2. ZonedDateTimeクラス

  • Instantクラス同様で瞬間を格納できるクラス。
  • エポックからの経過時間ではなく、
    「東京における 西暦2020年8月9日....235ナノ秒」という形式で瞬間を格納する。
  • どの都市を基準にするかを明確にするためにタイムゾーンという情報を含んでいる。
    タイムゾーンは、文字列で「Asia/Tokyo」や「Europe/London」などの表現。
  • タイムゾーンの情報は、ZoneIdクラスのインスタンスとして扱う。静的メソッドof()を利用する。
//ZoneDatedTimeの生成 現在日時取得
ZonedDateTime z1 = ZonedDateTime.now();

System.out.println(z1);    // =>2019-05-18T16:42:25.140+09:00[Asia/Tokyo]


//「東京時間 西暦2020年8月9日12時30分45秒60ナノ秒」を指定して取得
ZonedDateTime z2 = ZonedDateTime.of(2020, 8, 9, 12, 30, 45, 60, ZoneId.of("Asia/Tokyo"));

System.out.println(z2);// =>2020-08-09T12:30:45.000000060+09:00[Asia/Tokyo]
//InstantとZonedDateTimeの相互変換
Instant i3 = z2.toInstant();
ZonedDateTime z3 = i3.atZone(ZoneId.of("Europe/London"));

3. LocalDateTimeクラス

  • ZonedDateTimeクラスと似ているが、タイムゾーン情報だけは保存しない。
  • タイムゾーンの情報を保存しないことで、
    「どの瞬間か」確定できないが曖昧な時間情報を保持することができる。
//LocalDateTimeの生成方法
LocalDateTime l3 = LocalDateTime.now();
System.out.println(l3);  // =>2019-05-18T18:08:10.764

//「西暦2020年8月9日12時30分45秒60ナノ秒」を指定して取得
LocalDateTime l4 = LocalDateTime.of(2020, 8, 9, 12, 30, 45, 60);
System.out.println(l4);  // =>2020-08-09T12:30:45.000000060


//LocalDateTimeとZonedDateTimeの相互変換
ZonedDateTime z4 = l4.atZone(ZoneId.of("Asia/Tokyo"));
LocalDateTime l5 = z4.toLocalDateTime();
特定日時を指し示すクラスで共通して利用されるインスタンス生成メソッド(静的)
メソッド名 解説
now() 現在日時からインスタンスを生成する
of()/of~() 他の種類から変換してインスタンスを生成する
parse() "2020年8月9日"等の文字列からインスタンスを生成する

4. DurationクラスとPeriodクラス

  • 「2つの日付の間隔」と「2つの時刻の間隔」を表すクラス。
  • 「時・分・秒」の単位の比較的短い間隔を表す場合は、Durationクラスを使う。
  • サマータイム閏年などを考慮しながら日数期間を管理する場合は、Periodクラスを使う。
  • 両クラスとも、静的メソッドbetween(),ofDays(),ofMonths()を使うことでインスタンスを取得する。
LocalDate d1 = LocalDate.of(2020, 8, 9);
LocalDate d2 = LocalDate.of(2020, 8, 19);

//10日間を表す方法を生成
Period p1 = Period.ofDays(10);
Period p2 = Period.between(d1, d2);

//d2にさらに10日間プラス
LocalDate d3 = d2.plus(p2);
System.out.println(d3);