I need to validate a date string for the format dd/mm/yyyy
with a regular expresssion.
This regex validates dd/mm/yyyy
, but not the invalid
I'm working with an API that only accepts MM/DD/YYYY format. I couldn't find any other post that did leap years quite as well as Ofir's answer, so I tweaked it and am re-posting it here for anyone that might need it.
/^(?:(?:(?:0[13578]|1[02])(\/)31)\1|(?:(?:0[1,3-9]|1[0-2])(\/)(?:29|30)\2))(?:(?:1[6-9]|[2-9]\d)?\d{2})$|^(?:02(\/)29\3(?:(?:(?:1[6-9]|[2-9]\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0?[1-9])|(?:1[0-2]))(\/)(?:0[1-9]|1\d|2[0-8])\4(?:(?:1[6-9]|[2-9]\d)?\d{2})$/
"^(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.]((19|20)\\d\\d)$"
will validate any date between 1900-2099
I know it is a tangential answer to the question, but if the intention of the question is 'how do I validate a date?', then why not try letting the programming language do all the hard work (if you are using a language that can)?
e.g. in php
$this_date_object = date_create($this_date);
if ($this_date_object == false )
{
// process the error
}
Here is another version of regex to match any of the following date formats and allow leading zeros to be omitted:
Regex: ^[0-3]?[0-9].[0-3]?[0-9].(?:[0-9]{2})?[0-9]{2}$
Matches:
1/1/11 or 1.1.11 or 1-1-11 : true
01/01/11 or 01.01.11 or 01-01-11 : true
01/01/2011 or 01.01.2011 or 01-01-2011 : true
01/1/2011 or 01.1.2011 or 01-1-2011 : true
1/11/2011 or 1.11.2011 or 1-11-2011 : true
1/11/11 or 1.11.11 or 1-11-11 : true
11/1/11 or 11.1.11 or 11-1-11 : true
Debuggex Demo
For those who look at these and get completely confused, here is an excerpt from my script. Unfortunately, all it does is match valid numbers in a date time input, and 31st Feb will be marked as valid, but as so many have said, regex really isn't the best tool to do this test.
To match a date in the format 'yyyy-MM-dd hh:mm' (Or indeed in whatever order you please)
var dateerrors = false;
var yearReg = '(201[4-9]|202[0-9])'; ///< Allows a number between 2014 and 2029
var monthReg = '(0[1-9]|1[0-2])'; ///< Allows a number between 00 and 12
var dayReg = '(0[1-9]|1[0-9]|2[0-9]|3[0-1])'; ///< Allows a number between 00 and 31
var hourReg = '([0-1][0-9]|2[0-3])'; ///< Allows a number between 00 and 24
var minReg = '([0-5][0-9])'; ///< Allows a number between 00 and 59
var reg = new RegExp('^' + yearReg + '-' + monthReg + '-' + dayReg + ' ' + hourReg + ':' + minReg + '$', 'g');
$('input').filter(function () {return this.id.match(/myhtml_element_with_id_\d+_datetime/);}).each(function (e) {
if (e > 0) {
// Don't test the first input. This will use the default
var val = $(this).val();
if (val && !val.trim().match(reg)) {
dateerrors = true;
return false;
}
}
});
if (dateerrors) {
alert('You must enter a validate date in the format "yyyy-mm-dd HH:MM", e.g. 2019-12-31 19:30');
return false;
}
The above script starts off by building a regex object. It then finds all of the inputs whose id's match a certain pattern and then loops through these. I don't test the first input I find (if (e > 0)
).
A bit of explanation:
var reg = new RegExp('^' + yearReg + '-' + monthReg + '-' + dayReg + ' ' + hourReg + ':' + minReg + '$', 'g');
^
means start of match, whereas $
means end of match.
return this.id.match(/myhtml_element_with_id_\d+_datetime/);
\d+
means match a single or a contiguous sequence of integers, so myhtml_element_with_id_56_datetime
and myhtml_element_with_id_2_datetime
will match, but myhtml_element_with_id_5a_datetime
will not
Found this reg ex here
^(((0[1-9]|[12]\d|3[01])\/(0[13578]|1[02])\/((19|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|30)\/(0[13456789]|1[012])\/((19|[2-9]\d)\d{2}))|((0[1-9]|1\d|2[0-8])\/02\/((19|[2-9]\d)\d{2}))|(29\/02\/((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$
This validates the format mm/dd/yyyy
and valid dates correctly (but not m/d/yyyy
).
Some tests