【JavaScript】 Date 型 を扱う際のシンプルなルール【初心者向け】
様々な言語で Date
型は実装されますが、JavaScriptはブラウザで動作する関係上、最も慎重にタイムゾーンを考慮する必要がある言語の1つです。
ポイント
-
Date
を作るとき: Dateコンストラクタに文字列を渡さない -
String
を作るとき:toISOStinrg
を使用する
タイムゾーン
日本の朝9時は、ブラジルの朝9時ではありませんので日付/時刻を扱う際にはタイムゾーンによる影響を除外しておく必要があります。
UTC(世界協定時)
UTC(世界協定時)とは、世界標準となる時刻です。これを使用すれば、タイムゾーンによるズレをなくすことができそうです。
Webフロントエンドでの考慮対象
ただし、UTCをそのままユーザーに見せるわけにはいきませんし、バックエンドがUTCを受け付けないかもしれません。フロントエンドはユーザーとサーバーの界面としてこれを適切に処理する必要があります。
主に以下のポイントにおいて、Date
を考慮する必要があります。
- ユーザーから日付を取得する
- 日付を文字列としてバックエンドに送る
- データベースに格納する
- データベースから取得する
- フロントエンドに送り返す
- ユーザーのタイムゾーンで表示する
この中で、フロントエンドで注意すべきポイントは 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
を使用する
おまけ
ライブラリを使用するのが最もオススメです。
Discussion