JavaScriptでisNaNを使っても有効な日付か判断できないので注意

isNaNで有効な日付か判定

GoogleやChatGPTを使用して、JavaScriptで「2024-01-23」のような文字列の日付が有効な日付か判定するコードを調べると、isNanを使用した以下のようなコードをよく目にします。

JavaScript
function isValidDate(dateString) {
  const date = new Date(dateString)
  return !isNaN(date.getTime())
}

console.log(isValidDate('2024-01-23')) // true
console.log(isValidDate('2024-09-87')) // false
console.log(isValidDate('Hello')) // false

しかし、この判定だと「2024-02-30」のような存在しない日付もtrueになってしまいます。

これはJavaScriptでは2月の最終日に1日追加した「2024-02-30」は翌月の最初の日と判定されるからです。

JavaScript
function isValidDate(dateString) {
  const date = new Date(dateString)
  return !isNaN(date.getTime())
}

console.log(isValidDate('2024-02-30')) // true
console.log(new Date('2024-02-30')) // Fri Mar 01 2024 09:00:00 GMT+0900 (日本標準時)
console.log(new Date('2025-02-29')) // Sat Mar 01 2025 09:00:00 GMT+0900 (日本標準時)

JavaScriptで有効な日付か判定する正しい方法

前述のようなJavaScriptの仕様があるので、有効な日付か判定するには以下の点がtrueかどうかを判定すると良いです。

  • 日付の文字列が /^\d{4}[/-]\d{1,2}[/-]\d{1,2}$/ と一致するか
  • 文字列の日にちとnew Date()変換後の日にちが一致するか
  • ハイフンの数が0または2か

日付は年月日の分解が必要で、ハイフン ( - ) とスラッシュ ( / ) の2パターンが考えられるので、どちらでも対応できるようにisNaNを使わずに正規表現を使用した以下のコードを作成しました。

これならnew Date()で変換後に日にちが一致しているか確認する処理もあるので、有効な日付だと判定できます。

JavaScript
function isValidDate(dateString) {
  const regex = /^\d{4}[/\-]\d{1,2}[/\-]\d{1,2}$/
  const parts = dateString.split(/[/\-]/)
  const year = parseInt(parts[0], 10)
  const month = parseInt(parts[1], 10) - 1
  const day = parseInt(parts[2], 10)
  const date = new Date(year, month, day)
  const hyphenCount = dateString.split('-').length - 1

  if (
    regex.test(dateString) && 
    date.getDate() === day &&
    (hyphenCount === 0 || hyphenCount === 2)
  ) {
    return true
  }
  return false
}

console.log(isValidDate('2024-01-23')) // true
console.log(isValidDate('2024-09-87')) // false
console.log(isValidDate('Hello')) // false
console.log(isValidDate('2024-2-29')) // true
console.log(isValidDate('2024-02-30')) // false
console.log(isValidDate('2025-02-29')) // false
console.log(isValidDate('2025/03/21')) // true
console.log(isValidDate('2025/03-21')) // false

繰り返しになりますが、Googleで検索したり、ChatGPTで質問したりすると、isNaNだけで判定した間違ったコードが表示されることが多いので、JavaScriptで有効な日付が判定する際は注意が必要です。