I would use a regular expression. This one should work for you:
\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01])
This checks for:
\d{4}
- four digits
-
- followed by a hyphen
(?:0[1-9]|1[0-2])
- one of:
a. a zero followed by any number 1 to 9 (months 01 to 09)
b. a one followed by any number 0 to 2 (months 10 to 12)
-
- followed by a hyphen
(?:0[1-9]|[12][0-9]|3[01])
- using the same logic as above, any number from 01 to 31.
These more complex groups will mean that dates outside of the acceptable range (things like 2019-49-40) will also fail.
If you want to accept dates like 2019-1-4 (which, given you're working with SQL, is probably a bad plan, but just in case), simply put a ?
after the zeroes in the day and month sections (\d{4}-(?:0?[1-9]|1?[0-2])-(?:0?[1-9]|[12]?[0-9]|3?[01])
), to allow them to match 0
or 1
times (make them optional).
Hopefully you notice that if your only data source is a plain-old string, it is impossible to verify whether someone enters a date incorrectly (ie, Feb 9th, 2019 → 2019-02-09 and 2019-09-02 will both be "correct").
To do this in Javascript, you can use the RegExp.prototype.test
method. You can also leverage Array.prototype.filter
if you're making a new array (and Array.prototype.map
if you're working with DOM elements).
const dates = [...document.querySelectorAll('input')];
const wrongdates = dates.map(el => el.value).filter(date => !/\d{4}-(?:0[1-9]|1[0-2])-(?:0[1-9]|[12][0-9]|3[01])/.test(date));
console.log(wrongdates)
<input type="text" value="2019-01-31">
<input type="text" value="2019-15-52">
<input type="text" value="2005-09-17">
<input type="text" value="2001-06-13">
<input type="text" value="2001-06-13">
<input type="text" value="2001-06-13">
<input type="text" value="06-28-13">
<input type="text" value="Jan-12-2019">
You need the !
because RegExp.test
returns true
when it matches, and you're trying to make a list of incorrect dates.