【JavaScript】 Date 型 を扱う際のシンプルなルール【初心者向け】

2022/07/27に公開

様々な言語で Date型は実装されますが、JavaScriptはブラウザで動作する関係上、最も慎重にタイムゾーンを考慮する必要がある言語の1つです。

ポイント

  • Dateを作るとき: Dateコンストラクタに文字列を渡さない
  • Stringを作るとき: toISOStinrg を使用する

タイムゾーン

日本の朝9時は、ブラジルの朝9時ではありませんので日付/時刻を扱う際にはタイムゾーンによる影響を除外しておく必要があります。

UTC(世界協定時)

UTC(世界協定時)とは、世界標準となる時刻です。これを使用すれば、タイムゾーンによるズレをなくすことができそうです。

https://wa3.i-3-i.info/word11831.html

Webフロントエンドでの考慮対象

ただし、UTCをそのままユーザーに見せるわけにはいきませんし、バックエンドがUTCを受け付けないかもしれません。フロントエンドはユーザーとサーバーの界面としてこれを適切に処理する必要があります。

主に以下のポイントにおいて、Dateを考慮する必要があります。

  1. ユーザーから日付を取得する
  2. 日付を文字列としてバックエンドに送る
  3. データベースに格納する
  4. データベースから取得する
  5. フロントエンドに送り返す
  6. ユーザーのタイムゾーンで表示する

この中で、フロントエンドで注意すべきポイントは 1, 2, 5, 6 です。

DateはUTCを内包する

Date型は、それ自体が標準時の情報を持っており、またそれをタイムゾーンに合わせて変換することができます。したがって適切にDateオブジェクトを作成し保持することが最も重要です。

日本で実行
new Date();
// Wed Jul 27 2022 22:02:37 GMT+0900 (日本標準時)

シンプルなルール

適切にDateオブジェクトを作成し保持する ために以下のルールが有効です。

  • Dateを作るとき: Dateコンストラクタに文字列を渡さない
  • Stringを作るとき: UTC を使用する

Dateコンストラクタに文字列を渡さない

Dateコンストラクタは優秀なので、あらゆる文字列を評価してDateオブジェクトに変換することができます。

日本で実行
new Date("2012-10-12");
// Fri Oct 12 2012 09:00:00 GMT+0900 (日本標準時)

日付しか渡していないのにも関わらず、なぜか 09:00:00 になっています。予期しないズレやバグの原因になります。

数値から Date を作成する

これを避けるために、数値をコンストラクタに渡します。

日本で実行
new Date(2012, 10, 12)
// Mon Nov 12 2012 00:00:00 GMT+0900 (日本標準時)

これで、09:00:00 が解決できました。さらに引数を渡すことで、時間を指定することも可能です。

日本で実行
new Date(2012, 10, 12, 14, 50, 30)
// Mon Nov 12 2012 14:50:30 GMT+0900 (日本標準時)

月は0から始まる

JavaScriptの世界では、1月は0です。先ほどの実行例では、10月を渡したかと思いきや、結果はNov(11月)になっています。したがって、10月を指定する場合は 9 をコンストラクタに渡すのが正解となります。

日本で実行
new Date(2012, 9, 12, 14, 50, 30)
// Fri Oct 12 2012 14:50:30 GMT+0900 (日本標準時)

文字列変換する場合はtoISOStinrgする

Dateオブジェクトを文字列に変換する場合は toISOStringメソッドを使用して UTCフォーマットすることがおすすめです。こうすることで、文字列から再度元のDateを作成することができます。

日本で実行
new Date(2012, 9, 12, 14, 50, 30).toISOString();
// '2012-10-12T05:50:30.000Z'

UTC文字列からは元のDateを作成できます。
(「Dateコンストラクタに文字列を渡さない」と言ったすぐに文字列を渡していますが...UTC文字列と分かっていれば問題ありません)

日本で実行
new Date('2012-10-12T05:50:30.000Z');
// Fri Oct 12 2012 14:50:30 GMT+0900 (日本標準時)

まとめ

以下のルールを守ることで 日付によるズレを減らすことができます。

  • Dateを作るとき: Dateコンストラクタに文字列を渡さない
  • Stringを作るとき: toISOStinrg を使用する

おまけ

ライブラリを使用するのが最もオススメです。

https://github.com/you-dont-need/You-Dont-Need-Momentjs/blob/master/README.md#brief-comparison

Discussion