I get dates from a text area in the dd-mm-yyyy or dd/mm/yyyy format (the user is allowed to use - or /) How do I check (using a regex or php) if the date is valid? Is there a regex or php method done this far to validate dates in this format? I tried searching here but could not find anything.
A regular expression alone cannot validate a date because of the different number of days in months - especially for leap years.
/^(\d{1,2})(\/|-)(\d{1,2})\2(\d{2}|\d{4})$/
but above regex solves your problem of allowing - or / based on these format dd-mm-yyyy or dd/mm/yyyy
Here are some examples
//Date d/m/yy and dd/mm/yyyy
//1/1/00 through 31/12/99 and 01/01/1900 through 31/12/2099
//Matches invalid dates such as February 31st
'\b(0?[1-9]|[12][0-9]|3[01])[- /.](0?[1-9]|1[012])[- /.](19|20)?[0-9]{2}\b'
//Date dd/mm/yyyy
//01/01/1900 through 31/12/2099
//Matches invalid dates such as February 31st
'(0[1-9]|[12][0-9]|3[01])[- /.](0[1-9]|1[012])[- /.](19|20)[0-9]{2}'
//Date m/d/y and mm/dd/yyyy
//1/1/99 through 12/31/99 and 01/01/1900 through 12/31/2099
//Matches invalid dates such as February 31st
//Accepts dashes, spaces, forward slashes and dots as date separators
'\b(0?[1-9]|1[012])[- /.](0?[1-9]|[12][0-9]|3[01])[- /.](19|20)?[0-9]{2}\b'
//Date mm/dd/yyyy
//01/01/1900 through 12/31/2099
//Matches invalid dates such as February 31st
'(0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])[- /.](19|20)[0-9]{2}'
//Date yy-m-d or yyyy-mm-dd
//00-1-1 through 99-12-31 and 1900-01-01 through 2099-12-31
//Matches invalid dates such as February 31st
'\b(19|20)?[0-9]{2}[- /.](0?[1-9]|1[012])[- /.](0?[1-9]|[12][0-9]|3[01])\b'
//Date yyyy-mm-dd
//1900-01-01 through 2099-12-31
//Matches invalid dates such as February 31st
'(19|20)[0-9]{2}[- /.](0[1-9]|1[012])[- /.](0[1-9]|[12][0-9]|3[01])'
A very simplistic way would be to have a regular expression that checks for one of the formats, then make sure the input is converted to that first by replacing any characters:
$regexDate = '#\d\d\-\d\d\-\d\d\d\d#' ;
$dateIn = trim($_GET['date']) ;
//replace all / with - since our regex expects those
$dateIn = str_replace('/', '-', $dateIn) ;
if (preg_match($regexDate, $dateIn)) {
//valid date input
}
Hi, I'd use strftime and strptime. At first I'd convert string into "time" than back to string and compare it...
I highly recommend using the PHP methodstrtotime()
, as it will not only check to see if the format is valid, but if the time specified by the format is correct as well (i.e. there will never be a February 31st, but a regex might not catch this).
You can check to see if this is valid with if (strtotime($toCheck)) {
as it'll return FALSE
if it doesn't succeed (http://us2.php.net/strtotime).
EDIT:
You'll need to switch the order before you can check if the date is valid with strtotime
first like this:
$str = "07-31-1987";
$str = preg_replace('/([^-\/]+)[-\/]([^-\/]+)[-\/]([^-\/]+)/', '$2-$1-$3', $str);
echo date('r', strtotime($str)) . "\n"; // Fri, 31 Jul 1987 00:00:00 -0700
$date = str_replace("/", "-", $incoming);
$d = explode("-" , $date);
Re-assemble the parts and then run it through checkdate
if( !checkdate($d[1], $d[0], $d[2]) )
echo 'Not a recognised date' ;
I came up with this little function, it checks you use the format
DD(separator)MM(same separator)YYYY
With DD, MM and YYYY as integers.
function valid_date($input_date) {
if(!preg_match('/(?P<d>\d{2})(?P<sep>\D)(?P<m>\d{2})\2(?P<y>\d{4})/',$input_date, $aux_date))
return false;
else {
$aux = mktime(0,0,0,$aux_date['m'],$aux_date['d'],$aux_date['y']);
return $input_date == date('d'.$aux_date['sep'].'m'.$aux_date['sep'].'Y',$aux));
}
}
(Edited as sugested below)
You could use the datetime class, passing the date you want to validate to the constructor. If you have a valid date you'll get back a datetime object. If it's an invalid date the constructor will throw an exception, which you can catch and the handle the error accordingly.