Regular expression for dates

Hi everyone,

I came across this thread about validating dates:

http://www.sitepoint.com/forums/showthread.php?723638-PHP-regex-needed-for-dd-mm-yyyy-format

If you’re wanting, what seems to be, the mac daddy of patterns…
PHP Code:
#dd/MM/yyyy with leap years 100% integrated Valid years : from 1600 to 9999
function isDate($date){
return 1 === preg_match(
‘~^(((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))))$~’,
$date
);
}

The thing is that I don’t know how to implement the regular expression. The code below always gives me boolean false. The format of the date is d MM yy although ideally I’d want: D, d MM yy. I have a form with a datepicker which sends the dates to another script. Only those dates in the correct format should be sent.

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (!empty($_POST['arrive])) {
$a =  isDate($_POST['arrive']);
var_dump($a);
}
}

Does anyone know what I’m doing wrong? Is my function call ok?

Thank you for any assistance!

What is the format of the date inside $_POST[‘arrive’] ? Is it the d mm yy format you mention?

Missing that apostrophe

if ($_SERVER['REQUEST_METHOD'] == 'POST') {
if (!empty($_POST['arrive[COLOR="#FF0000"]'[/COLOR]])) {
$a =  isDate($_POST['arrive']);
var_dump($a);
}
} 
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
	if (!empty($_POST['arrive'])) {
		$a =  isDate($_POST['arrive']);
		var_dump($a);
	}
}

I might mention that I call datepicker with this format

<script type="text/javascript">
	$(function() {
		$( "#datepicker_from" ).datepicker({ dateFormat: 'MM d, yy' });
	});
</script>

Then in my input field I modify the shown format like

$FromShow = date('F j, Y', strtotime($From));
<input type="text" id="datepicker_from" name="from" value="$FromShow" class="text" />

And on post I convert to the format I wish to store it in.

$From = (isset($_POST['from']) ? date('Y-m-d', strtotime($_POST['from'])) : '');

You might be able to do something like this in your case.

The comment above the code says that it is validating dd/mm/yyyy format. Do you have the date in that format before performing the test? If the date starts in a different format then simply being able to convert the date to a different format will require testing that the original format is valid first making the subsequent validation unnecessary.

The regular expression could be rearranged to validate any other arrangement of the date provided that the day and month are two digit numbers and the year is a four digit number between 1600 and 9999 other than 4882 or 8182.

I think the comment about the valid date range may be slightly incorrect regarding two dates - 29/02/4882 and 29/02/8182 are valid dates within the specified range that it does not appear to cater for from viewing the code. They are the only two leap years in the range where the year is not divisible by 4.

Hi phpMyDirectory, Drummin and felgall,

thank you for all of your input and please excuse my late reply.

@ Drummin,

Missing that apostrophe

Thanks, I fixed that but I always get boolean false. I used a dd/mm/yy format.

I might mention that I call datepicker with this format

Thank you for providing that example. The date function which includes the strtotime function looks like something I could use. Do you know of a technique to remove the forward slashes in a string such as “13/05/2014”? I’d like to use this date in the below date function. If this works then I could skip the regular expression pattern.

date('F j, Y', strtotime($From));

@ felgall,

I tried dd/mm/yy instead of dd/mm/yyyy otherwise I’d have 2 years after the month.

You’ll see formatting options here. I found I couldn’t get things just like I wanted, which is why I did the formatting like I did.

Thanks for the link Drummin, however for my validation I need to keep the dd/mm/yy format.

I tried the following but get 1 January 1970 instead of 22 August 2014. Replacing the forward slashes with a dash or dot, results in 8 August 2014.

$d = '22/08/2014';
$d2 = date('n F  Y', strtotime($d));
echo $d2;

Do you know what else I can do?

Thanks, I appreciate your help.

You need to either convert the date to a format strtotime() understands before using it - see https://php.net/manual/en/datetime.formats.date.php

or use a different function (eg. mktime) that will allow you to enter the date in pieces after you split the day month and year.

Yes. You can break the date apart with list and then put it back together in an order strtotime can use. Also, I think you want ‘j’ for the day and not ‘n’, which would be the month.

<?php
$d = '22/08/2014';
//$d = date('d/m/y');
//$d = date('d/m/Y');

list($day,$month,$year) = explode('/',$d);
$date2 = $year . "-" . $month . "-" . $day;	
//$d2 = date('n F  Y', strtotime($d));
$d2 = date('j F  Y', strtotime($date2));

echo $d2;
?>

Hi Stephen and Drummin,

thanks again for your help. I’m experiencing a few issues with my validation and so have not been able to try the date conversion methods. I’ll get back to you on this.

Thanks, and have a good weekend and Easter.