Java 8の日付/時刻APIについて、実務的に使う頻度の高そうなモノだけを簡潔にまとめました。
java.time.LocalDateクラス
- 特徴
- LocalDateはimmutable(Calenderはmutableだった)
- Calenderでは月が0から始まっていたが、LocalDateは1から始まる
- 月に0を渡すと存在しない日付なので実行時エラーになる
- インスタンス生成系の便利メソッド
- now
- of
- parse
LocalDate a = LocalDate.now();
System.out.println(a); // YYYY-MM-DD
LocalDate b = LocalDate.of(2017, 10, 17);
System.out.println(b); // 2017-10-17
LocalDate c = LocalDate.parse("2017-10-17");
System.out.println(c); // 2017-10-17
System.out.println(c.getYear()); // 2017
System.out.println(c.getMonthValue()); // 10
System.out.println(c.getDayOfMonth()); // 17
System.out.println(c.getDayOfWeek()); // "TUESDAY"
System.out.println(c.getDayOfWeek().getValue()); // 2
LocalDate d = c.plusDays(30);
System.out.println(c); // 2017-10-17 ※immutableなので元の値は変わらない
System.out.println(d); // 2017-11-16
java.time.LocalTimeクラス
- LocalTimeはimmutable
- 24時間で時間を扱い、午前/午後は区別しない
LocalTime a = LocalTime.of(0, 1, 2);
System.out.println(a); // 00:01:02
LocalTime b = a.plusHours(12);
System.out.println(a); // 00:01:02 ※immutableなので元の値は変わらない
System.out.println(b); // 12:01:02
java.time.LocalDateTimeクラス
- 基本的な仕様はLocalDate / LocalTimeと同じ
java.time.format.DateTimeFormatterクラス
- LocalDate / LocalTime / LocalDateTime とも、
format
メソッドで使う - DateTimeFormatterクラスに定義されている定数(フォーマッター)を引数にできる
フォーマッター | 例 |
---|---|
BASIC_ISO_DATE | 20171017 |
ISO_LOCAL_DATE | 2017-10-17 |
ISO_LOCAL_TIME | 10:15:30 |
LocalDateTime dateTime = LocalDateTime.of(2017, 10, 17, 10, 15, 30);
System.out.println(dateTime.format(DateTimeFormatter.BASIC_ISO_DATE)); // 20171017
System.out.println(dateTime.format(DateTimeFormatter.ISO_LOCAL_DATE)); // 2017-10-17
System.out.println(dateTime.format(DateTimeFormatter.ISO_LOCAL_TIME)); // 10:15:30
java.time.Durationクラス
- 日付の差、時刻の差を取得できる
LocalDateTime start = LocalDateTime.of(2017, 10, 17, 0, 0);
LocalDateTime end = LocalDateTime.of(2017, 11, 17, 0, 0);
Duration d = Duration.between(start, end);
System.out.println(d.toDays()); // 31(日)
System.out.println(d.toHours()); // 744(時間)
(参考&注意)
Java 8にはjava.time.Periodクラスという、期間を取得するためのAPIもあります。
ところが、このAPIは、期間を「○年と○ヶ月と○日」という形式で求めるモノです。
いわゆる「日数」を取得する目的で利用すると期待結果と異なるので、勘違いしないように注意しなければなりません。
LocalDate start = LocalDate.of(2017, 10, 17);
LocalDate end = LocalDate.of(2017, 11, 17);
Period p = Period.between(start, end);
System.out.println(p.getMonths()); // 1ヶ月
System.out.println(p.getDays()); // 0日 (注)期待結果を「31日」と想定しているとバグる