8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【JavaScript】日付の存在チェックにおけるタイムゾーンの影響

Last updated at Posted at 2025-03-21

はじめに

Webページの制作で「年」「月」「日」で入力欄が分かれているようなフォームを設置した経験がある方も多いのではないでしょうか。こうしたフォームだと「11月31日」のような存在しない日付を入力できてしまうので、「日付が正しいか」のチェックは必要不可欠です。

▼ 2024 ▼ 11 ▼ 31

よくあるチェック方法の1つとして「getDate で返る『日』が入力された値と同じか」が挙げられると思いますが、下記のようなコードの場合、ある状況下において 「正しい日付なのに誤った日付だと判定される」 事象が発生します。

// 11月に31日は存在しない
year = 2024
month = 11
date = 31

// 「2024-11-31」は「2024-12-01」扱いとなる
if (new Date(`${year}-${month}-${date}`).getDate() != date) {
  // getDate()で「1」が返るためdateと一致しない
  console.log('誤った日付です')
}

ローカルタイムゾーンの影響

「国内サイトに海外からアクセスした」ケースを想定します。今回はGoogle Chromeのデベロッパーツールでタイムゾーンを「サンフランシスコ(UTC-7)」に設定しコンソール上で動作を検証してみました。

スクリーンショット 2025-03-19 21.21.58.png

すると、「2024-11-30」は正しい日付ですが、「誤った日付である」と誤判定してしまっています。

スクリーンショット 2025-03-19 19.33.52.png

getDate() で何が返っているか見てみましょう。
スクリーンショット 2025-03-19 19.35.36.png

「2024-11-30」と入力しているにも関わらず、「29」が返ってきています。

getDateの仕様

JavaScriptのドキュメントには下記のように記されています。

getDate() メソッドは、地方時に基づき、指定された日付の「日」を返します。

今回挙げた例の場合、日付文字列をそのまま判定処理に渡した結果、タイムゾーンの影響を受けて意図した挙動とは違う動きとなっていました。
JavaScriptにおける日付の扱い全般に言えることですが、ブラウザや環境によって異なる解釈をされる余地が生まれないよう、タイムゾーンを明示的に指定する等の対応が必要でした。

あるいは、単に「入力された日付と同じこと」を確認したいだけならば、ローカルタイムゾーンの影響を受けない getUTCDate() を使っても良いかもしれません。

(2025/3/24追記)
コメントでご指摘をいただきました。new Dateに日付文字列を渡して正しく解釈されると保証されているのはISO8601形式の場合だけで、このケースも「(多くのクライアントで)UTC時刻として扱われる」から結果的に合っている、というものです。

スクリーンショット 2025-03-19 19.36.56.png

まとめ

  • JavaScriptで日付を扱う際はタイムゾーンによく留意すること
  • 特に、海外からもアクセスがあるようなWebサービスは要注意

参考

Date.prototype.getDate() - JavaScript | MDN
Date.prototype.getUTCDate() - JavaScript | MDN

8
7
2

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
8
7

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?