【 Java 】Java8から追加された日付のAPI

## ■　はじめに
Java勉強につき、メモを残します。
下記内容は、備忘録レベルで書いているので間違い等あるかもしれません。
参考にする際にはその点ご認識のほどお願いします。。

## ■ 概要
今回は、非推奨メソッドが多くなったDateクラス、
そしてフォーマットや解析に使用していた、スレッドセーフではないSimpleDateFormatの代替としてJava8から追加されたjava.timeのクラスを触ってみました。
使用感を掴むため、生成、formatでのフォーマット、parseでの解析、betweenで経過時間を取得する処理を検証してみました。

1.Dateの代替クラス
・LocalDate
・LocalTime
・LocalDateTime
・OffsetDateTime
・ZonedDateTime

2.SimpleDateFormatの代替
・DateTimeFormatter

3.経過時感を取得するクラス
・Period
・Duration

※日付、時間、オフセット、タイムゾーンなど、要件に合うクラスを選択して実装するのが良いと思います。
※全てのクラスがスレッドセーフです。
## ■ 検証ソース
```java
import java.time.*;
import java.time.format.DateTimeFormatter;

public class JavaTime {
    public static void main(String[] args) {
        // 生成
        System.out.println("---- 生成 ----");
        LocalDate localDate = LocalDate.of(2025, 1, 27);
        System.out.println("LocalDate:" + localDate);
        LocalTime localTime = LocalTime.of(9, 0);
        System.out.println("LocalTime:" + localTime);
        LocalDateTime localDateTime = LocalDateTime.of(2025, 1, 27, 9, 0);
        System.out.println("LocalDateTime:" + localDateTime);
        LocalDateTime localDateTimeSecond = LocalDateTime.of(2025, 1, 27, 9, 0, 50);
        System.out.println("LocalDateTime:" + localDateTimeSecond);
        OffsetDateTime offsetDateTime = OffsetDateTime.of(localDateTime, ZoneOffset.ofHours(9));
        System.out.println("OffsetDateTime:" + offsetDateTime);
        ZonedDateTime zonedDateTime = ZonedDateTime.of(localDateTime, ZoneOffset.systemDefault());
        System.out.println("ZonedDateTime:" + zonedDateTime);

        // parse(String型の日付を解析し、各java.timeの型に変換する)
        System.out.println("---- parse ----");
        System.out.println("LocalDate:" + LocalDate.parse("2025-01-27", DateTimeFormatter.ISO_DATE));
        System.out.println("LocalTime:" + LocalTime.parse("09:00", DateTimeFormatter.ISO_LOCAL_TIME));
        System.out.println("LocalDateTime:" + LocalDateTime.parse("2025-01-27T09:10", DateTimeFormatter.ISO_LOCAL_DATE_TIME));
        System.out.println("LocalDateTime:" + LocalDateTime.parse("2025-01-27T09:10:20", DateTimeFormatter.ISO_LOCAL_DATE_TIME));
        System.out.println("OffsetDateTime:" + OffsetDateTime.parse("2025-01-27T09:10:20+09:00", DateTimeFormatter.ISO_OFFSET_DATE_TIME));
        System.out.println("ZonedDateTime:" + ZonedDateTime.parse("2025-01-27T09:10:20+09:00[Asia/Tokyo]", DateTimeFormatter.ISO_ZONED_DATE_TIME));

        // format(各java.timeの型をString型にフォーマットする)
        System.out.println("---- format ----");
        System.out.println("LocalDate:" + localDate.format(DateTimeFormatter.ISO_DATE));
        System.out.println("LocalTime:" + localTime.format(DateTimeFormatter.ISO_LOCAL_TIME));
        System.out.println("LocalDateTime:" + localDateTime.format(DateTimeFormatter.ISO_LOCAL_DATE_TIME));
        System.out.println("OffsetLocalDateTime:" + offsetDateTime.format(DateTimeFormatter.ISO_OFFSET_DATE_TIME));
        System.out.println("ZonedLocalDateTime:" + zonedDateTime.format(DateTimeFormatter.ISO_ZONED_DATE_TIME));

        // 日付の比較(年数、月数、日数)
        System.out.println("---- between:LocalDate ----");
        LocalDate startLocalDate = LocalDate.of(2024,1,1);
        LocalDate endLocalDate = LocalDate.of(2025,12,31);
        Period period = Period.between(startLocalDate, endLocalDate);
        System.out.println("LocalDate_年数:" + period.getYears());
        System.out.println("LocalDate_月数:" + period.getMonths());
        System.out.println("LocalDate_日数:" + period.getDays());

        System.out.println("---- between:LocalTime ----");
        LocalTime startLocalTime = LocalTime.of(0,0);
        LocalTime endLocalTime = LocalTime.of(23,59);
        Duration localTimeDuration = Duration.between(startLocalTime, endLocalTime);
        System.out.println("LocalTime_日数:" + localTimeDuration.toDays());
        System.out.println("LocalTime_時間:" + localTimeDuration.toHours());
        System.out.println("LocalTime_分数:" + localTimeDuration.toMinutes());
        System.out.println("LocalTime_秒数:" + localTimeDuration.toSeconds());
        System.out.println("LocalTime_ミリ秒数:" + localTimeDuration.toMillis());

        // 日付の比較(日数、時間、分数、秒数、ミリ秒数)
        System.out.println("---- between:LocalDateTime ----");
        LocalDateTime startLocalDateTime = LocalDateTime.of(2025,1,1,0,0,0);
        LocalDateTime endLocalDateTime = LocalDateTime.of(2025,12,31,0,0,0);
        Duration localDateTimeDuration = Duration.between(startLocalDateTime, endLocalDateTime);
        System.out.println("LocalDateTime_日数:" + localDateTimeDuration.toDays());
        System.out.println("LocalDateTime_時間:" + localDateTimeDuration.toHours());
        System.out.println("LocalDateTime_分数:" + localDateTimeDuration.toMinutes());
        System.out.println("LocalDateTime_秒数:" + localDateTimeDuration.toSeconds());
        System.out.println("LocalDateTime_ミリ秒数:" + localDateTimeDuration.toMillis());

        System.out.println("---- between:OffsetDateTime ----");
        OffsetDateTime startOffsetDateTime = OffsetDateTime.of(2025,1,1,0,0,0,0,ZoneOffset.ofHours(9));
        OffsetDateTime endOffsetDateTime = OffsetDateTime.of(2025,12,31,0,0,0,0,ZoneOffset.ofHours(9));
        Duration offsetDuration = Duration.between(startOffsetDateTime, endOffsetDateTime);
        System.out.println("OffsetDateTime_日数:" + offsetDuration.toDays());
        System.out.println("OffsetDateTime_時間:" + offsetDuration.toHours());
        System.out.println("OffsetDateTime_分数:" + offsetDuration.toMinutes());
        System.out.println("OffsetDateTime_秒数:" + offsetDuration.toSeconds());
        System.out.println("OffsetDateTime_ミリ秒数:" + offsetDuration.toMillis());

        System.out.println("---- between:ZonedDateTime ----");
        ZonedDateTime startZonedDateTime = ZonedDateTime.of(2025,1,1,0,0,0,0,ZoneOffset.systemDefault());
        ZonedDateTime endDateZonedTime = ZonedDateTime.of(2025,12,31,0,0,0,0,ZoneOffset.systemDefault());
        Duration ZonedDuration = Duration.between(startZonedDateTime, endDateZonedTime);
        System.out.println("ZonedDateTime_日数:" + ZonedDuration.toDays());
        System.out.println("ZonedDateTime_時間:" + ZonedDuration.toHours());
        System.out.println("ZonedDateTime_分数:" + ZonedDuration.toMinutes());
        System.out.println("ZonedDateTime_秒数:" + ZonedDuration.toSeconds());
        System.out.println("ZonedDateTime_ミリ秒数:" + ZonedDuration.toMillis());
    }
}
```


```java:出力結果
---- 生成 ----
LocalDate:2025-01-27
LocalTime:09:00
LocalDateTime:2025-01-27T09:00
LocalDateTime:2025-01-27T09:00:50
OffsetDateTime:2025-01-27T09:00+09:00
ZonedDateTime:2025-01-27T09:00+09:00[Asia/Tokyo]

---- parse ----
LocalDate:2025-01-27
LocalTime:09:00
LocalDateTime:2025-01-27T09:10
LocalDateTime:2025-01-27T09:10:20
OffsetDateTime:2025-01-27T09:10:20+09:00
ZonedDateTime:2025-01-27T09:10:20+09:00[Asia/Tokyo]

---- format ----
LocalDate:2025-01-27
LocalTime:09:00:00
LocalDateTime:2025-01-27T09:00:00
OffsetLocalDateTime:2025-01-27T09:00:00+09:00
ZonedLocalDateTime:2025-01-27T09:00:00+09:00[Asia/Tokyo]

---- between:LocalDate ----
LocalDate_年数:1
LocalDate_月数:11
LocalDate_日数:30

---- between:LocalTime ----
LocalTime_日数:0
LocalTime_時間:23
LocalTime_分数:1439
LocalTime_秒数:86340
LocalTime_ミリ秒数:86340000

---- between:LocalDateTime ----
LocalDateTime_日数:364
LocalDateTime_時間:8736
LocalDateTime_分数:524160
LocalDateTime_秒数:31449600
LocalDateTime_ミリ秒数:31449600000

---- between:OffsetDateTime ----
OffsetDateTime_日数:364
OffsetDateTime_時間:8736
OffsetDateTime_分数:524160
OffsetDateTime_秒数:31449600
OffsetDateTime_ミリ秒数:31449600000

---- between:ZonedDateTime ----
ZonedDateTime_日数:364
ZonedDateTime_時間:8736
ZonedDateTime_分数:524160
ZonedDateTime_秒数:31449600
ZonedDateTime_ミリ秒数:31449600000
```
## ◽️ 参考資料
https://docs.oracle.com/javase/jp/8/docs/api/java/time/format/DateTimeFormatter.html

https://docs.oracle.com/javase/jp/8/docs/api/java/time/LocalDate.html

https://docs.oracle.com/javase/jp/8/docs/api/java/time/LocalTime.html

https://docs.oracle.com/javase/jp/8/docs/api/java/time/LocalDateTime.html

https://docs.oracle.com/javase/jp/8/docs/api/java/time/OffsetDateTime.html

https://docs.oracle.com/javase/jp/8/docs/api/java/time/ZonedDateTime.html 

https://docs.oracle.com/javase/jp/8/docs/api/java/time/Duration.html

https://docs.oracle.com/javase/jp/8/docs/api/java/time/Period.html