日時を扱うクラス

# Dateクラス
* 現在日時の取得。
* クラスのなのでDateクラスのオブジェクトを生成する

`import java.util.Date;`が必要。
(コレクション作成時も`java.util.ArrayList;`した)
```java
package text.section_21;

 import java.util.Date;


public class DateTime_Test1 {
	
	public static void main(String[] args) {
		// 現在日時の取得
		Date date = new Date();
		
		// 出力
		System.out.println(date);
		
	}

	
}
```
実行結果
```Java
Fri Feb 16 09:32:23 JST 2024
```
曜日、月、日、時間：分：秒　日本時間　年　
上記の順で出力される。

# Calenderクラス
* 任意の日時を設定、取得できる。
*  クラスのなのでDateクラスのオブジェクトを生成する
*  CalendarクラスのMONTHは0から始まる。(つまり実行結果の1は2月を示す)

Dateクラスの各フィールド一覧
YEAR：    年を示す
MONTH：  月を示す(0から始まる)
DATE：    日を示す
HOUR：	時間を示す
MINUTE：	分を示す
SECOND：	秒を示す

初めにCalendarクラスをインポートする。
```java
// インポート
import java.util.Calendar;
```

## new演算子ではなく`.getInstance()`でオブジェクト生成
>getInstanceメソッドは、呼び出すごとに現在の日付と時間に初期化された状態で、オブジェクトを返します。[引用元](https://www.sejuku.net/blog/20275#index_id2)

```java
// Calenderクラスのオブジェクト生成
Calendar calendar = Calendar.getInstance();
```
## `getTime`メソッドと`get`メソッドの違い
```Java
// Calenderクラスのオブジェクト生成
Calendar calendar = Calendar.getInstance();
		
		System.out.println("getTimeの現在日時：" + calendar.getTime().toString());
		
		int year = calendar.get(Calendar.YEAR);
		System.out.println("getで取り出した年：" + year);
```
実行結果
```Java
getTimeの現在日時：Fri Feb 16 11:10:30 JST 2024
getで取り出した年：2024
```
1.  `オブジェクト名.getTime()`:オブジェクトから現在時刻・日付を取得する。
1.  `オブジェクト名.get(Calendar.フィールド名)`：オブジェクトに対してCalendarクラスのフィールド変数を指定して取り出す。

《注意点》
getで取得した月の値は、月またぎの関係で実際より１ヶ月遅れている。(
今日は2024/02/16)

```java
System.out.println("月は"+calendar.get(Calendar.MONTH));
```
実行結果
```Java
月は1
```
月が１ヶ月遅れて表示されることへの対策
```java
int month = calendar.get(Calendar.MONTH) + 1;
		System.out.println("実際の月は" + month);
```
実行結果
```Java
実際の月は2
```

## `setTime`
`.setTime(Calender.フィールド変数,任意の値)`
setTimeメソッドでCalenderクラスのフィールド変数に対して、指定の日時を設定してオブジェクト`calendar`に格納する。
setTimeメソッドは指定の日時を設定できるが、日付を増やしたり減らすことはできない。

# ３ヶ月後を表示させる方法
Dateクラス、
Calenderクラス、
getInstance、
setTimeメソッド
上記を使用して、現在から３ヶ月後の日時を表示させたい
```Java
 // インポート
import java.util.Calendar;
import java.util.Date;

public class DateTime_Test1 {
	
	public static void main(String[] args) {
		
		// 現在時刻・日時を格納するオブジェクト生成
		Date nowdate = new Date();
		System.out.println("現在の日付: " + nowdate);
		
		// 現在時刻・日時をclに格納する
		Calendar cl = Calendar.getInstance();
		cl.setTime(nowdate);
		
		// ３ヶ月後の日付を計算
		cl.add(Calendar.MONTH, 3);		
		// ３ヶ月後の日付を取得
		Date future = cl.getTime();
		System.out.println("3ヶ月後は：" + future);

	}	
}
```
実行結果
```
現在の日付: Fri Feb 16 12:02:57 JST 2024
3ヶ月後は：Thu May 16 12:02:57 JST 2024
```
ちなみに、Calendarクラスに`getInstance`で作成したオブジェクトにも現在時刻は入っているが表示が下記のようになるので注意
```Java
		// 現在時刻・日時をclに格納する
		Calendar cl = Calendar.getInstance();
		cl.setTime(nowdate);
		System.out.println(cl);
```
実行結果
```java
java.util.GregorianCalendar[time=1708052777600,areFieldsSet=true,areAllFieldsSet=true,lenient=true,zone=sun.util.calendar.ZoneInfo[id="Asia/Tokyo",offset=32400000,dstSavings=0,useDaylight=false,transitions=10,lastRule=null],firstDayOfWeek=1,minimalDaysInFirstWeek=1,ERA=1,YEAR=2024,MONTH=1,WEEK_OF_YEAR=7,WEEK_OF_MONTH=3,DAY_OF_MONTH=16,DAY_OF_YEAR=47,DAY_OF_WEEK=6,DAY_OF_WEEK_IN_MONTH=3,AM_PM=1,HOUR=0,HOUR_OF_DAY=12,MINUTE=6,SECOND=17,MILLISECOND=600,ZONE_OFFSET=32400000,DST_OFFSET=0]
```
## SimpleDateFormatクラス
* Dateクラスのフォーマットを指定した表示にすることができる
* 初期値のフォーマットは、「yyyy/MM/dd H」
* `import java.text.SimpleDateFormat;`インポート必須

y：年を示す
M：月を示す
d：日を示す
H：0時から23時を示す
h：1時から12時を表す(15時の場合、3と表示)
m：分を示す
s：秒を示す
《実装方法》
先ほど実践した３ヶ月後の日時を取得したコードの最後に、
下記のコードを追記します。
SimpleDateFormatクラスのコンストラクタに引数として、`"yyyy/MM/dd/H:mm"`を渡すことで指定の日時時間表示の形でオブジェクト`sdf`を生成する.
↓
そしてそのオブジェクト`sdf`を使って`sdf.format(future));`し、フォーマットを変える。

```java
// SimpleDateFormatを使用
//　オブジェクト生成
SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd/H:mm");
		System.out.println("フォーマットした3ヶ月後の日時：" + sdf.format(future));
```
実行結果　
2行目がSimpleDateFormatクラスによって表示を変化させて表示
```java
3ヶ月後は：Thu May 16 13:01:55 JST 2024
フォーマットした3ヶ月後の日時：2024/05/16/13:012
```

## Data and Time API
`Date`クラス、`Calender`クラスは日時を全て扱う。対して`Data and Time API`に含まれるクラスは、日付と時刻を扱クラスが分かれている。

クラスは3種類
1. LocalDate : 日付
1. LocalTime : 時刻
1. LocalDateTime : 日付と時刻
### `LocalDate`
日付の取得
```java
package text.section_21;

import java.time.LocalDate;

public class DateTime2_Test1 {

	public static void main(String[] args) {
		// 現在時刻の取得
		LocalDate date1 = LocalDate.now();
		// 現在時刻の出力
		System.out.println(date1);
		
		// 指定の時刻
		LocalDate date2 = LocalDate.of(2000,1,1);
		// 指定時刻の出力
		System.out.println(date2);		 
	}
}
 ```
 実行結果
 ```java
2024-02-16
2000-01-01
```
### `LocalTime`
時刻を取得
```java
package text.section_21;

import java.time.LocalTime;

public class DateTime2_Test1 {

	public static void main(String[] args) {
		// 現在時刻の取得
		LocalTime time1 = LocalTime.now();
		// 現在時刻の出力
		System.out.println(time1);
		
		// 指定の時刻
		LocalTime time2 = LocalTime.of(20,00,58);
		// 指定時刻の出力
		System.out.println(time2);		 
	}
}
```
実行結果
```java
22:02:59.253607
20:00:5
```
1行目が現在時刻で、
2行目は20時00分58秒を指定した結果。

### `LocalDateTime`
日付と時刻の両方を取得
```java
package text.section_21;

import java.time.LocalDateTime;

public class DateTime2_Test1 {

	public static void main(String[] args) {
		// 現在時刻の取得
		LocalDateTime datetime1 = LocalDateTime.now();
		// 現在時刻の出力
		System.out.println(datetime1);
		
		// 指定の時刻
		LocalDateTime datetime2 = LocalDateTime.of(2000,01,01,14,30,30);
		// 指定時刻の出力
		System.out.println(datetime2);		 
	}
}
```
実行結果
```Java
2024-02-16T22:13:44.146266
2000-01-01T14:30:30
```
1行目が、現在の日付と時刻。Tより前が、日付、後ろが時刻。
2行目は、指定した日付と時刻。2000年1月1日14時30分30秒を指定。

## `DateTimeFormatter`クラス

`SimpleDateFormat`クラスと似ている。
最初に`DateTimeFormatter`クラスのコンストラクタに引数を指定して生成したオブジェクトでフォーマットする。その際、コンストラクタに渡す引数を表示したいフォーマットに指定する。
```Java
// DateTimeFormatterクラスのオブジェクトを生成する
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yy/MM/dd/hh/mm/ss");
```


《実装例》
```Java
package text.section_21;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class DateTime2_Test1 {

    public static void main(String[] args) {
        // 指定の時刻
        LocalDateTime dt = LocalDateTime.of(2024, 1, 1, 14, 30, 30);
        // 指定時刻の出力
        System.out.println("フォーマット指定前：" + dt);

        // DateTimeFormatterクラスのオブジェクトを生成する
        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yy/MM/dd/hh/mm/ss");
        // DateTimeFormatterクラスのオブジェクトでフォーマットする
        String dtfdatetime = dt.format(dtf);

        System.out.println("フォーマット指定後：" + dtfdatetime);
    }
}
```
実行結果
```java
フォーマット指定前：2024-01-01T14:30:30
フォーマット指定後：24/01/01/02/30/30
```

# 日時の比較
下記の3つのメソッドを使用する
1. isAfter : 日付が比較対象の日付より**後の日付か**判定する
1. isBefore : 日付が比較対象の日付より**前の日付か**判定する
1. isEqual : 日付が比較対象の**日付と等しいか**判定する

```java
package text.section_22;

import java.time.LocalDateTime;
//
public class DateTime2_Test6 {

   public static void main(String[] args) {				
      LocalDateTime dateTime1 = LocalDateTime.of(1999, 01, 10, 02, 30, 40);
	LocalDateTime dateTime2 = LocalDateTime.of(2000, 02, 20, 03, 40, 50);
	LocalDateTime dateTime3 = LocalDateTime.of(1999, 01, 10, 02, 30, 40);
	
      //日付が比較対象の日付より後の日付か判定する 
	if (dateTime1.isAfter(dateTime2)) {
	   System.out.println("日付が比較対象の日付より後の日付です");
	}
	
      //日付が比較対象の日付より前の日付か判定する 
	if (dateTime1.isBefore(dateTime2)) {
	   System.out.println("日付が比較対象の日付より前の日付です");
	}
	
      //日付が比較対象の日付と等しい日付か判定する 
	if (dateTime1.isEqual(dateTime3)) {
	   System.out.println("日付が比較対象の日付と同じ日付です");
	}

   }

}
```
実行結果
```Java
日付が比較対象の日付より前の日付です
日付が比較対象の日付と同じ日付です
 ```

`A.isAfter(B)`で、AはBより以前の時刻か？を判定している。実装例の一番めの比較では`false`なので出力されていない。

## 日付の加算と減算　`plusYears()` `minusYears()` 
* 日付を加算や減算することができる
* 日付を加算する場合は、年、月、日を指定

 Years ：　年
 Months　：　月
 Days　：　日

《エラーの例》
![スクリーンショット 2024-02-17 8.59.49.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3570384/cc1c0ce7-a86b-a6f8-4a80-3c7b61da226b.png)
String型に変更してしまっている`date`に対して、minusメソッドは使えないよ！とのこと。そりゃそうだ。
[参考URL](https://qiita.com/KenyaSaitoh/items/6644c14017c45918a5a1#:~:text=%E3%83%AD%E3%83%BC%E3%82%AB%E3%83%AB%E6%97%A5%E6%99%82%E3%82%92%E8%A1%A8%E3%81%99%E3%82%AF%E3%83%A9%E3%82%B9%E3%81%AB%E3%81%AF%E3%80%81%E6%97%A5%E4%BB%98%EF%BC%8B%E6%99%82%E9%96%93,LocalTime%E3%81%A8%E3%80%813%E7%A8%AE%E9%A1%9E%E3%81%82%E3%82%8A%E3%81%BE%E3%81%99%E3%80%82)
正しくは下記。
《実装例》
```Java
package text.section_22;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;

public class DateTime2_Test7 {

	public static void main(String[] args) {
		
		//LocalDateTimeで現在時刻の取得
		LocalDateTime dateTime = LocalDateTime.now();
		System.out.println("現在：" + dateTime);
		
		//1年前の時刻を取得・表示
		System.out.println(dateTime.minusYears(1));
		
		//フォーマットを変更
		DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy/MM/dd");
		String date = dateTime.format(dtf);
		System.out.println("フォーマット変更：" + date);
		
	}

}
```
実行結果
```java
現在：2024-02-17T09:08:38.941503
2023-02-17T09:08:38.941503
フォーマット変更：2024/02/17
```
## 日付の差分
下記の書式で求められる
```java
Period.between(取得した日時.toLocalDate(), 差分を求める日時.toLocalDate());
```
* `Period`クラスを使用
↓
* `Period`クラスのメソッド`between`に差分を求めたい日時を渡す
↓
* その際、日付に対して`toLocaldate()`を適応して日付のみを抽出
↓
* `Period`クラスの下記のメソッドで計算した差分の値を取得
`getYears` `getMonths` `getDays	`

```Java
package text.section_22;
import java.time.LocalDateTime;
import java.time.Period;


public class DateTime2_Test9 {

	public static void main(String[] args) {
		LocalDateTime dateTime1 = LocalDateTime.of(2000,01,01,00,00,00);
		LocalDateTime dateTime2 = LocalDateTime.of(2001,02,10,01,30,00);
		
		//日付の差分を求める
		Period period = Period.between(dateTime1.toLocalDate(),dateTime2.toLocalDate());
			System.out.println( "年の差分は" + period.getYears() + "年");
			System.out.println( "月の差分は" + period.getMonths() + "月");
			System.out.println( "日の差分は" + period.getDays() + "日");

	}

}
```

実行結果
```
年の差分は1年
月の差分は1月
日の差分は9日 
```
## 時刻の差分
```Java
Duration.between(取得した日時, 取得した日時);
```
計算した時刻の差分は下記のメソッドで取得する
`toHours()` `toSeconds()` `toMinutes()`
コードの記述手順は日付の差分と同じ。