【JavaScript ~カウントダウンタイマーの作成~】勉強メモ13

JavaScriptちゃんと学習中。
今回は<b>Dateオブジェクトを使ってカウントダウンタイマーの作成をする</b>についてです。
ほぼ自分の勉強メモです。
過度な期待はしないでください。


手順
-
１、設定した未来時刻をパラメータで受け取る
２、ゴール時間から現在時刻を引く
３、計算結果を返す
<br>


未来時刻を設定
-
　-Dateオブジェクトが持つ値に対して、日付と時刻の値をそれぞれ設定するメソッドが用意されている。
　それが以下のメソッド

|メソッド|説明|
|:---:|:---:|
|setFullYear(　)　|　　　　年の値を設定する　　　　|
|setMonth( )　|月の値を設定する|
|setDatet( )　|日の値を設定する|
|setHours( )　|時の値を設定する|
|setMinutes( )　|分の値を設定する|
|setSeconds( )　|秒の値を設定する|

　-Dateオブジェクトのメソッド一覧はこちらを参照
　[MDN web docs – Date](https://developer.mozilla.org/ja/docs/Web/JavaScript/Reference/Global_Objects/Date/getTime)
<br>

- Dateオブジェクトで時間を設定

　setHours、setMinutes、setSecondsメソッドで、時、分、秒をそれぞれ設定する必要があるが、
　先ず、Dateオブジェクトを使いたい場合、最初に<b>インスタンスの生成する</b>必要がある事に注意。
　インスタンスの生成をした事で、Dateオブジェクトを使い日時の出力や計算が出来るようになる。
　なぜなら、その計算の基準日となっているのが現在日時だからです。
　なので、インスタンス化し現在の日時を記憶したDateオブジェクトを使い日時の出力や計算が出来るようになる。

```.js:JavaScript 
'use strict';
// newはオブジェクトをインスタンス化させる為のもの
// 現在の時刻（基準値）を変数goalに代入
let goal = new Date();
// メソッド使用して、２３：59：５９と設定
goal.setHours(23);
goal.setMinutes(59);
goal.setSeconds(59);

// ここで変数goalの中見を確認
console.log(goal);
```

```.text:出力結果
// 例えば今日が2020年11月１３日なら
// 時、分、秒以外設定されていないので現在の年月日が取得される
Fri Nov 13 ２３：59：５９
```
<br>

関数を定義
-

- 設定した時刻をパラメータで受け取る関数を定義

　-残り時間を算出する為の関数を記載
　関数の定義は、functionを使用して行う。また、引数を使用して、関数に追加情報を与える。

```.text:書き方
function 関数名（引数名）{
  //まとめたい処理内容
　console.log(`私の名前は${引数名}`です);
};

// 引数を受け取る関数を呼び出す
定数名(値) → その値は関数の引数に代入される
```

　-パラメータとして時間が設定されたDateオブジェクトを引数として受け取る関数を定義する
　

```.js:JavaScript 
'use strict';

// 関数countdownを定義
// 引数にsetを追加して値を受け取られるようにする（引数名はどんな名前でも可能）
function countdown(set) {
  //まとめたい処理内容
}

let goal = new Date();
goal.setHours(23);
goal.setMinutes(59);
goal.setSeconds(59);

// 定数counterに、countdown関数の処理を代入
// 設定した時刻が代入されている変数goalの値を関数の引数として渡す
const counter = countdown(goal);
```
<br>

- 残り時間を算出する為のプログラムを記載

　-countdown関数の中身の処理を記載
　残り時間を算出する為には、設定した時刻から現在の時刻を引くという計算をする。
　その為には、先ずは現在の時刻を記憶したDateオブジェクトを生成する、つまりインスタンスの生成をする。

```.js:JavaScript 
function countdown(set) {
  // 現在の時刻（基準値）を変数nowに代入
  const now = new Date();
}
```
<br>
　-残り時間を算出する計算式を記載
　先ず、設定した時刻から現在の時刻を引く為に、getTime( )メソッドを使用。
　getTime( )メソッドは、1970年1月1日0時00分から、そのオブジェクトの基準日になっている
　日時迄に経過したミリ秒を取得するメソッド。
　例えば、現在2020年11月13日午後12時00分だと、getTime( )メソッドで1605279599309ミリ秒で出る。
　これを設定した時刻のミリ秒から引くという計算をする。

```.js:JavaScript 
function countdown(set) {
  const now = new Date();
  // 設定した時刻をが入っている引数と現在の時刻を記憶しているnowを使用して
  // getTime( )メソッドでミリ秒で残り時間を算出し、定数restに代入
  const rest = set.getTime() - now.getTime();
}
```
<br>

　-定数restのミリ秒をもとに、秒、分、時、日を計算
　
　先ずは秒から。
　元の数値がミリ秒なので、1000で割れば全体の秒数が出る。
　さらに、その答えを60で割れば分が出ます。すなわちの割った余りが秒になる。

　例：39455000÷1000÷60=657 余り35
　ここでいうと35が秒数

　これをコードで書くと下記のようになる。
　

```.js:JavaScript 
function countdown(set) {
  const now = new Date();
  const rest = set.getTime() - now.getTime();

  const sec = Math.floor(rest / 1000) % 60;
}
```
　1000で割った小数点以下は秒に満たないものなのでfloorメソッドで切り捨てる。
　また、プログラムにおける演算式の%は、計算した余りを表示するものなの注意（決して割り算ではない）
<br>
　次に分ですが、
　上で計算した答えの結果を60で割った答えの余りが時になる。
　657÷60=10 余り57
　ここでいうと57が分になる。

　これをコードで書くと下記のようになる。
　

```.js:JavaScript 
function countdown(set) {
  const now = new Date();
  const rest = set.getTime() - now.getTime();
  const sec = Math.floor(rest / 1000) % 60;

  const min = Math.floor(rest / 1000 / 60) % 60;
}
```
　ここも1000で割った小数点以下は分に満たないものなのでfloorメソッドで切り捨てる。
　また、プログラムにおける演算式の%は、計算した余りを表示するものなの注意（決して割り算ではない）
<br>

　次に時です。
　
　上で計算した答えの結果を24で割った答えの余りが時になる。
　10÷24=0 余り10
　ここでいうと10が時になる。

　これをコードで書くと下記のようになる。
　

```.js:JavaScript 
function countdown(set) {
  const now = new Date();
  const rest = set.getTime() - now.getTime();
  const sec = Math.floor(rest / 1000) % 60;
  const min = Math.floor(rest / 1000 / 60) % 60;

  const hours = Math.floor(rest / 1000 / 60 / 60) % 24;
}
```
　ここも1000で割った小数点以下は1時間に満たないものなのでfloorメソッドで切り捨てる。
　また、プログラムにおける演算式の%は、計算した余りを表示するものなの注意（決して割り算ではない）
<br>

　最後に日ですが、
　上の計算 10÷24=0 余り10
　の余りじゃない方が日になるので、
　ここでいうと0が日になる。

　これをコードで書くと下記のようになる。
　

```.js:JavaScript 
function countdown(set) {
  const now = new Date();
  const rest = set.getTime() - now.getTime();
  const sec = Math.floor(rest / 1000) % 60;
  const min = Math.floor(rest / 1000 / 60) % 60;
  const hours = Math.floor(rest / 1000 / 60 / 60) % 24;

  const days = Math.floor(rest / 1000 / 60 / 60 / 24);
}
```
　今後は、余りを表示させたい訳ではなく、割り算の結果を表示させたいのでこうなる。
<br>

　-こうして出揃った、秒、分、時、日を配列にして定数に代入して、呼び出し元にリターンさせる。

```.js:JavaScript 
function countdown(set) {
  const now = new Date();
  const rest = set.getTime() - now.getTime();
  const sec = Math.floor(rest / 1000) % 60;
  const min = Math.floor(rest / 1000 / 60) % 60;
  const hours = Math.floor(rest / 1000 / 60 / 60) % 24;
  const days = Math.floor(rest / 1000 / 60 / 60 / 24);

  const count = [days, hours, min, sec];
  return count;
}
```
　「return 値」と書くことで、関数はその値を戻り値として返す。
<br>

- 現在の完成形

```.js:JavaScript
'use strict';

function countdown(set) {
  const now = new Date();

  const rest = set.getTime() - now.getTime();
  const sec = Math.floor(rest / 1000) % 60;
  const min = Math.floor(rest / 1000 / 60) % 60;
  const hours = Math.floor(rest / 1000 / 60 / 60) % 24;
  const days = Math.floor(rest / 1000 / 60 / 60 / 24);
  const count = [days, hours, min, sec];

  return count;
}

let goal = new Date();
goal.setHours(23);
goal.setMinutes(59);
goal.setSeconds(59);

const counter = countdown(goal);
```

<br>

- 保存されたデータをもとに代入

　-後は、関数の処理データが代入された定数counterをもとに、　
　テンプレートに代入させるだけ。

　テンプレート例：
　`${counter[1]}時間${counter[2]}分${counter[3]}秒`
 
　配列の要素の取得の仕方は、<b>配列名[配列番号]</b>
　配列番号は、0から１、２・・・と始まることに注意

　最後に、getElementByIdメソッドを使って要素取得し、textContentプロパティを使用し出力する。

```.html:HTML
<p>後、<span id="timer"></span>で1日が終わります。</p>
```

```.js:JavaScript
'use strict';

function countdown(set) {
  const now = new Date();

  const rest = set.getTime() - now.getTime();
  const sec = Math.floor(rest / 1000) % 60;
  const min = Math.floor(rest / 1000 / 60) % 60;
  const hours = Math.floor(rest / 1000 / 60 / 60) % 24;
  const days = Math.floor(rest / 1000 / 60 / 60 / 24);
  const count = [days, hours, min, sec];

  return count;
}

let goal = new Date();
goal.setHours(23);
goal.setMinutes(59);
goal.setSeconds(59);

const counter = countdown(goal);
const time = `${counter[1]}時間${counter[2]}分${counter[3]}秒`;
document.getElementById('timer').textContent = time;
```

```.text:出力結果
後、10時間0分48秒で1日が終わります。
```
<br>

過去投稿記事
-
[【JavaScript ~変数・定数、if文・switch文~】勉強メモ](https://qiita.com/k-yasuhiro/items/1fb63f0881faf67bcb29)
[【JavaScript ~for文、配列、オブジェクトについて~】勉強メモ②](https://qiita.com/k-yasuhiro/items/6625942cc901feb6bfdf)
[【JavaScript ~関数について~】勉強メモ③](https://qiita.com/k-yasuhiro/items/52e3ebb79bb0248a7c5e)
[【JavaScript ~クラスやインスタンス、メソッドについて~】勉強メモ④](https://qiita.com/k-yasuhiro/items/52e3ebb79bb0248a7c5e)
[【JavaScript ~ファイルの分割について~】勉強メモ⑤](https://qiita.com/k-yasuhiro/items/209eda27bbc61ae961a1)
[【JavaScript 読み込み】勉強メモ⑥](https://qiita.com/k-yasuhiro/items/fe3fc2bd7b14fe4f3968)
[【JavaScript ~配列のメソッド~】勉強メモ⑦](https://qiita.com/k-yasuhiro/items/279b7bb59f112f917c51)
[【JavaScript ~コールバック関数~】勉強メモ⑧](https://qiita.com/k-yasuhiro/private/ded7e2cad732774d059e)
[【JavaScript ~HTMLを置き換え、ダイアログボックス~】勉強メモ⑨](https://qiita.com/k-yasuhiro/items/7a72bf38d78b141d6fac)
[【JavaScript ~イベント~】勉強メモ⑩](https://qiita.com/k-yasuhiro/items/b0d4037d0edaae38a495)
[【JavaScript ~イベント(入力内容を取得)とDateオブジェクト~】勉強メモ11](https://qiita.com/k-yasuhiro/items/fa586154cf7064eb7058)
[【JavaScript ~Mathオブジェクト~】勉強メモ12](https://qiita.com/k-yasuhiro/items/b931a15fb71322ee3cca)