日付が有効かどうかチェックする方法
JavaScriptで日付が有効かどうかチェックを行うには、 Dateオブジェクトへの変換/正規表現による形式チェックなどの方法があります。 今回はDateオブジェクトへの変換、正規表現での有効かどうかのチェックを紹介します。
- Dateオブジェクトへの変換
- 正規表現での判断
また、日付の範囲チェックのサンプルコードもあるので、合わせてご覧ください。
Dateオブジェクトに変換して有効かどうか判断する
文字列の日付が有効かどうかチェックする簡単な方法はDateオブジェクトへの変換です。
有効でない日付をDateオブジェクトに変換し、getDateメソッドなどで日付の情報を取得すると、NaNが返ります。これを利用して有効かどうか判断します。
let strDate = "2022/22/22"
let date = new Date(strDate)
isNaN(date.getDate())
// -> true
有効でない日付「2022年22月22日」で試してみました。望み通り、isNaNでの判定で「true」が返され有効でないことが確認できます。
「20210101」の場合「yyyyMMdd」の形式で有効な日付ですが、Dateオブジェクトへの変換はうまくいかず上記の方法では有効でないと判断されます。
let strDate = "20210101"
let date = new Date(strDate)
isNaN(date.getDate())
// -> true
「yyyyMMdd」のような形式の場合は、形式の変換と組み合わせて実行する必要があります。
日付の範囲チェック
JavaScriptで日付の範囲チェックを行う場合は、Dateオブジェクトを使用します。今回は、フォームのテキストエリアから1つの日付を取得した際の範囲チェックを想定して、サンプルを作成してみました。
テキストエリア(日付インターフェース)から取得した日付が指定範囲内かどうかチェックするには、Dateオブジェクトにしてから大小を比較します。
※テキストエリアで2021年9月27日を指定した場合のサンプルコードです。テキストエリアのvalueを取得すると「”2021-09-27"」となります。
※Dateオブジェクトを作成するときの月は-1をします。(例 12月の場合「11」を指定する
let maxDate=new Date(2021,12-1,31) // 日付範囲の上限
let minDate=new Date(2021,1-1,1) // 日付範囲の下限
maxDate.getFullYear()+"年"+(maxDate.getMonth()+1)+"月"+maxDate.getDate()+"日"
// -> "2021年12月31日"
minDate.getFullYear()+"年"+(minDate.getMonth()+1)+"月"+minDate.getDate()+"日"
// -> "2021年1月1日"
let inputStrDate="2021-09-27" // テキストエリア(日付インターフェース)の値
let inputDate=new Date(inputStrDate)
inputDate.getFullYear()+"年"+(inputDate.getMonth()+1)+"月"+inputDate.getDate()+"日"
// -> "2021年9月27日"
maxDate >= inputDate && minDate <= inputDate
// -> true
このように、文字列で取得した日付をDateオブジェクトに変換してから比較することで、正確に範囲チェックを行うことができます。
下限を下回る日付を入力した場合は以下のようになります。
let inputStrDate="2020-11-01" // テキストエリア(日付インターフェース)の値
let inputDate=new Date(inputStrDate)
inputDate.getFullYear()+"年"+(inputDate.getMonth()+1)+"月"+inputDate.getDate()+"日"
// -> "2020年11月1日"
maxDate >= inputDate && minDate <= inputDate
// -> false
正規表現でのチェック方法
正規表現でも文字列が日付かどうかチェックすることができます。正規表現で文字列型の日付の形式(フォーマット)をチェックすることで日付かどうか判断する方法です。今回は、日付の形式(フォーマット)でよく使用される「yyyy/MM/dd」の形式チェックをしてみます。
let date="2021/09/27"
date.match(/\d{4}\/\d{2}\/\d{2}/)
// -> [“2021/09/27”, index: 0, input: "2021/09/27", groups: undefined]
2021年9月27日を「yyyy/MM/dd」の形式にした文字列を生成します。 ”2021/09/27”
次に、その文字列で「match」メソッドを呼び、引数には正規表現を指定しています。
この正規表現(/\d{4}\/\d{2}\/\d{2}/)が、日付の形式(フォーマット)を指定しています。スラッシュが多くわかりづらいですが、分解すると以下のようになります。
- 全体の囲い(正規表現を表すときに使用):/ 〜 /
- 年(yyyy):\d{4}
- /(区切り):\/
- 月(MM):\d{2}
- /(区切り):\/
- 日(dd):\d{2}
年月日では「\d」を使用して数字のチェックを行います。「{n}」で数字の桁数を指定しています。年は数字が4つ連続するかどうか、月日は数字が2つ連続するかどうかをチェックしています。
スラッシュ(/)の区切りは「\/」のように記述します。ただのスラッシュ「/」では、正規表現の囲いと同じ文字になるため、正規表現の開始/終了と判断されてしまいます。そのためエスケープをします。(「\」をつける)
「yyyy/MM/dd」となっていない場合は次のようになります。
let date="2021/9/27"
date.match(/\d{4}\/\d{2}\/\d{2}/)
// -> null
0埋めしているかどうか関係ない「yyyy/M/d」の形式をチェックしたい場合は、桁数指定を範囲で行います。「{1,2}」を使用します。
let date="2021/9/27"
date.match(/\d{4}\/\d{1,2}\/\d{1,2}/)
// -> [“2021/9/27”, index: 0, input: "2021/9/27", groups: undefined]
let date="2021/9/7"
date.match(/\d{4}\/\d{1,2}\/\d{1,2}/)
// -> [“2021/9/7”, index: 0, input: "2021/9/7", groups: undefined]
let date="2021/09/07"
date.match(/\d{4}\/\d{1,2}\/\d{1,2}/)
// -> [“2021/09/07”, index: 0, input: "2021/09/07", groups: undefined]
しかし、この正規表現では日付の形式をチェックするだけなので、有効かどうかチェックする場合は、Dateオブジェクトに変換する方法を採用したほうがいいです。
日付の形式チェック
日付の形式をチェックは上で紹介した正規表現を使用します。ここでは様々な日付の形式を正規表現でチェックしてみたいと思います。
- yyyyMMdd
- yyyy/MM/dd
- yyyy年MM月dd日
- yyyy-MM-dd
- yyyy MM dd
- yyMMdd
※月日の0埋めなしをチェックしたい場合は「{2}」を「{1,2}」にします。
let date = ""
date = "20210927"
date.match(/\d{4}\d{2}\d{2}/)
// -> ["20210927", index: 0, input: "20210927", groups: undefined]
date = "2021/09/27"
date.match(/\d{4}\/\d{2}\/\d{2}/)
// -> ["2021/09/27", index: 0, input: "2021/09/27", groups: undefined]
date = "2021年09月27日"
date.match(/\d{4}年\d{2}月\d{2}/)
// -> ["2021年09月27", index: 0, input: "2021年09月27日", groups: undefined]
date = "2021-09-27"
date.match(/\d{4}-\d{2}-\d{2}/)
// -> ["2021-09-27", index: 0, input: "2021-09-27", groups: undefined]
date = "2021 09 27"
date.match(/\d{4} \d{2} \d{2}/)
// -> ["2021 09 27", index: 0, input: "2021 09 27", groups: undefined]
date = "210927"
date.match(/\d{2}\d{2}\d{2}/)
// -> ["210927", index: 0, input: "210927", groups: undefined]