【JavaScript】toLocaleDateStringで日付フォーマット 🗓

## toLocaleDateStringで簡単に日付フォーマット

これまで日付フォーマットする時って、`getFullYear()`とか`getMonth() + 1`とかで頑張ってフォーマットしていたんですけど、`toLocaleDateString()`を使う方法を知り、備忘録として取り上げました。
`toLocaleDateString()`は、 Dateオブジェクトが持つ日付と時刻の値を、指定したロケールの形式で文字列として返します。

### 構文
```js
Dateオブジェクト.toLocaleString(locales, options)
```

例)
```js
const now = new Date()
const dateString = now.toLocaleDateString('ja-JP')
console.log(dateString) // → 2022/12/12
```

optionをつけてさらに自在にフォーマット
```js
const options = {
  year: 'numeric',
  month: 'short',
  day: 'numeric',
  weekday: 'short',
}
const now = new Date()
const dateString = now.toLocaleDateString('ja-JP', options)
console.log(dateString) // → 2022年12月12日(月)
```
必要なoptionだけ取ればok
下記は曜日なしの場合
```js
const options = {
  year: 'numeric',
  month: 'short',
  day: 'numeric',
  // weekday: 'short', → 曜日オプションコメントアウト
}
const now = new Date()
const dateString = now.toLocaleDateString('ja-JP', options)
console.log(dateString) // → 2022年12月12日
```

曜日だけ表示したい場合
```js
const options = {
  // year: 'numeric',
  // month: 'short',
  // day: 'numeric',
  weekday: 'short',
}
const now = new Date()
const dateString = now.toLocaleDateString('ja-JP', options)
console.log(`${dateString}曜日`) // → 月曜日
```

## チャットアプリなどによくある、日付の表示例

引数に日付が渡ってきて、その日付が今日中なら時間表示、昨日なら昨日、一週間いないなら曜日表示、それより前ならyyyy年mm月dd日と表示させる関数の例です。

```js
const dateFormat = (updateDate) => {
  const date = new Date(updateDate);
  const hours = date.getHours().toString()
  const minutes = date.getMinutes().toString().padStart(2, '0')

  const today = new Date();
  const yesterday = new Date(today);
  yesterday.setDate(today.getDate() - 1);

  const oneWeekAgo = new Date(today);
  oneWeekAgo.setDate(today.getDate() - 7);

  const options = {
    year: "numeric",
    month: "short",
    day: "numeric",
  };
  const updateDateString = date.toLocaleDateString("ja-JP", options);
  const todayDateString = today.toLocaleDateString("ja-JP", options);
  const yesterdayDateString = yesterday.toLocaleDateString("ja-JP", options);

  if (oneWeekAgo.getTime() < date.getTime()) {
    if (updateDateString === todayDateString) {
      return `${hours}:${minutes}`;
    } else if (updateDateString === yesterdayDateString) {
      return "昨日";
    } else {
      const options = {
        weekday: "short",
      };
      return `${date.toLocaleDateString("ja-JP", options)}曜日`;
    }
  } else {
    return updateDateString;
  }
};
```

例えば今日が2022/12/13日だとして上記関数で返却された値をconsoleすると下記のようになります。
```js
console.log(dateFormat("2022-12-13 13:30:00")); // → 13:30
console.log(dateFormat("2022-12-12 13:30:00")); // → 昨日
console.log(dateFormat("2022-12-11 13:30:00")); // → 日曜日
console.log(dateFormat("2022-12-6 13:30:00")); // → 2022年12月6日
```

### コード解説

```js
const date = new Date(updateDate);
const hours = date.getHours().toString()
const minutes = date.getMinutes().toString().padStart(2, '0')
```
上記部分では渡ってくる実引数を元にdateオブジェクトのインスタンスを生成し、表示用の時間を定数に格納しています。実引数が今日の日付だった場合は`hours`、`minutes`をreturnします。

:::note warn
`padStart()`とは文字列が指定した長さになるように、現在の文字列を他の文字列で (必要に応じて繰り返して) 延長。延長は、現在の文字列の先頭から適用されます。
`minutes`にpadStart(2, '0')としているので、2桁になるよう0で埋めてくれる。
例)
padStartなし → 12:0
padStartあり → 12:05
:::


```js
const today = new Date();
const yesterday = new Date(today);
yesterday.setDate(today.getDate() - 1);

const oneWeekAgo = new Date(today);
oneWeekAgo.setDate(today.getDate() - 7);
```
上記部分では本日のdateインスタンスを生成し、`setDate`で日付をセットして昨日、一週間前を取得しています。
これをif文に使用し、昨日だったら..一週間以内だったら..のように返す値を分ける形です。

```js
const options = {
    year: "numeric",
    month: "short",
    day: "numeric",
};
const updateDateString = date.toLocaleDateString("ja-JP", options);
const todayDateString = today.toLocaleDateString("ja-JP", options);
const yesterdayDateString = yesterday.toLocaleDateString("ja-JP", options);
```
今回の本題、`toLocaleDateString`の使用です。
optionを設定し、`toLocaleDateString`で表示用に変更したstringをそれぞれ定数に格納しています。

```js
if (oneWeekAgo.getTime() < date.getTime()) {
    if (updateDateString === todayDateString) {
      return `${hours}:${minutes}`;
    } else if (updateDateString === yesterdayDateString) {
      return "昨日";
    } else {
      const options = {
        weekday: "short",
      };
      return `${date.toLocaleDateString("ja-JP", options)}曜日`;
    }
  } else {
    return updateDateString;
  }
```
表示切り替え用の条件文です。`if (oneWeekAgo.getTime() < date.getTime())`でセットしておいた一週間前の日付と渡ってくる実引数を`getTime()`で経過ミリ秒数に変更し、一週間以内かどうか比較しています。
一週間以内だったらさらにネストしたif文で、本日だったら時間を返し、昨日だったら昨日というstringを返しています。
一週間以内だけど今日でも昨日でもない場合に、曜日だけを返したいので、再び`toLocaleDateString`を使用し、曜日だけを取るoptionを設定している流れです。
```js
 const options = {
    weekday: "short",
    };
    return `${date.toLocaleDateString("ja-JP", options)}曜日`;
```

## まとめ

YYYY/mm/ddにフォーマットするだけでも今までは年や月を取得して代入して..ってコネコネして表示させていましたが、`toLocaleDateString`だと数行でフォーマットできるんですね！
自分が知らないだけでもっと簡単にできる方法ありそうです..
もっといい方法あるよ！ここの部分、こういうコードに変えてもいいかも！っていう人はコメントでぜひ教えてください！