【Java】Time APIについて

## はじめに
今回はJavaのTime APIについて調べました。
Java8から新しい日時関連のクラス群がjava.timeパッケージとして追加され、その中でも代表的なクラスを抜粋し、使用方法についてまとめました。

## ゴール
本記事はTime APIの代表的なクラスの使用方法を理解し、活用できるようになることをゴールとしています。

## java.timeパッケージの代表的クラス
本記事で使用するjava.timeパッケージのクラスと機能について下記にまとめます。

* Instantクラス  
    * 世界における、ある「瞬間」の時刻を、ナノ秒単位で厳密に指し示し、保持する。
    * エポック秒を表すlong値と1秒未満のナノ秒を表すint値(0-999,999,999)からなる日時。  
* ZonedDateTimeクラス  
    * 世界における、ある「瞬間」の時刻を、ナノ秒単位で厳密に指し示し、保持する。
    * タイムゾーン付きの日時。  
    例：2015-12-15T23:30:59.999+09:00[Asia/Tokyo]
* LocalDateTimeクラス  
    * 日常的に使われる「曖昧な日時」を保持する。
    * タイムゾーンのない日時。  
    例：2015-12-15T23:30:59.999

## 使用例

### ・Instantクラス

```java
import java.time.*;

public class Main {
    public static void main(String[] args) {

        //Instantの生成を行い、現在時刻を取得する。
        Instant now = Instant.now();
        System.out.println(now);
        System.out.println("経過秒数：" + now.getEpochSecond());
    }
}
```
実行結果

```
2022-03-14T08:13:44.910839Z
経過秒数：1647245624
```
Instantは、世界のどこででも同じ基準となる絶対的な時点を表します。  
厳密にはうるう秒とかややこしいですが、簡単にいうと1970-01-01T00:00:00Zから経過した秒数です。
 
### ・ZonedDateTimeクラス

```java
import java.time.*;

public class Main {
    public static void main(String[] args) {

        //ZonedDateTimeの生成し現在時刻を取得する。
        ZonedDateTime dateTime = ZonedDateTime.of(2022, 2, 4, 20, 40, 24, 24, ZoneId.of("Asia/Tokyo"));
        System.out.println(dateTime);
        System.out.println("西暦：" + dateTime.getYear());
        System.out.println("月：" + dateTime.getMonth());
        System.out.println("日：" + dateTime.getDayOfMonth());
        System.out.println("時：" + dateTime.getHour());
        System.out.println("分：" + dateTime.getMinute());
        System.out.println("秒：" + dateTime.getSecond());
        System.out.println("ナノ秒：" + dateTime.getNano());
        System.out.println("タイムゾーン：" + dateTime.getZone());
    }
}
```
実行結果

```
2022-02-04T20:40:24.000000024+09:00[Asia/Tokyo]
西暦：2022
月：FEBRUARY
日：4
時：20
分：40
秒：24
ナノ秒：24
タイムゾーン：Asia/Tokyo
```
ZonedDateTimeはタイムゾーン情報(ZoneId)を持ちます。  
日時は、日付(年と月と日)と時刻(時と分と秒とナノ秒)で構成されます。

### ・LocalDateTimeクラス

```java
import java.time.*;

public class Main {
    public static void main(String[] args) {

        //LocalDateTimeの生成し現在時刻を取得する。
        LocalDateTime dateTime = LocalDateTime.of(2022, 2, 4, 20, 40, 24, 24);
        System.out.println(dateTime);
        System.out.println("西暦：" + dateTime.getYear());
        System.out.println("月：" + dateTime.getMonth());
        System.out.println("日：" + dateTime.getDayOfMonth());
        System.out.println("時：" + dateTime.getHour());
        System.out.println("分：" + dateTime.getMinute());
        System.out.println("秒：" + dateTime.getSecond());
        System.out.println("ナノ秒：" + dateTime.getNano());      
    }
}
```
実行結果

```
2022-02-04T20:40:24.000000024
西暦：2022
月：FEBRUARY
日：4
時：20
分：40
秒：24
ナノ秒：24
```
LocalDateTimeはタイムゾーン情報を持ちません。  
日時は、日付(年と月と日)と時刻(時と分と秒とナノ秒)で構成されます。

## その他の日時を表すクラス
LocalDateTimeからさらにいくつかの情報を削ったクラスを下記の表にまとめます。

|  クラス  |  年  |  月  |  日  |  時間  |  ゾーン  |  用途や例  |
| :----: | :----: | :----: | :----: | :----: | :----: | :----: |
|  LocalDate  |  ○  |  ○  |  ○  |  ×  |  ×  |  誕生日など  |
|  LocalTime  |  ×  |  ×  |  ×  |  ○  |  ×  |  アラーム時刻など  |
|  Year  |  ○  |  ×  |  ×  |  ×  |  ×  |  公開年など  |
|  YearMonth  |  ○  |  ○  |  ×  |  ×  |  ×  |  カード有効期限など  |
|  Month  |  ×  |  ○  |  ×  |  ×  |  ×  |  決済月など  |
|  MonthDay  |  ×  |  ○  |  ○  |  ×  |  ×  |  日本の祝日など  |

## さいごに
Time APIの代表的なクラスの使用方法について理解できましたか？
日付を扱うクラスは他にもありますが、それぞれの特徴を理解してぜひ活用してみてください。