Page 1 of 1

Date Regex (dd/mm/yy)

Posted: Fri Feb 10, 2006 10:40 am
by jayshields
Hi guys.

I suck with regex.

All i want to do is make sure the user input is a date. In this format: dd/mm/yy.

I don't want to use checkdate, because I'll have to explode on / and the user could be entering ds/sfds, which would give me some sort of error when i pass $var[2] to checkdate.

I just want the pattern to match number number slash number number slash number number.

My attempt:

Code: Select all

([0-9]{2})/([0-9]{2})/([0-9]{2})
It gives unknown modifier error for the slash, and I have tried \/ \\/ /\ [ /.] [/] etc etc. Existing date regex's I've seen don't support the format I want :(

Thanks for any help!

Posted: Fri Feb 10, 2006 10:45 am
by feyd

Code: Select all

$p = '#^\s*([0-9]{2})/([0-9]{2})/([0-9]{2})\s*$#';
preg_match($p,$string,$matches);
should work fine.. You should send it through mktime() or something as well though..

Posted: Fri Feb 10, 2006 11:11 am
by jayshields
Thanks feyd.

Could you/someone just explain to me what those extra characters do/mean? So I know for next time?

Thanks.

Posted: Fri Feb 10, 2006 11:18 am
by feyd
the stickies explain them.

Posted: Fri Feb 10, 2006 11:59 am
by raghavan20
but how about a date, "2/2/98" ???

Posted: Fri Feb 10, 2006 12:18 pm
by pickle
raghavan20 wrote:but how about a date, "2/2/98" ???

Code: Select all

$pattern = ":(\d+)/(\d+)/(\d+):";
Although to be anal, ~jayshields did mention:
jayshields wrote:I just want the pattern to match number number slash number number slash number number.

Posted: Fri Feb 10, 2006 12:20 pm
by raghavan20
pickle wrote:
raghavan20 wrote:but how about a date, "2/2/98" ???

Code: Select all

$pattern = ":(\d*)/(\d*)/(\d*):";
Although to be anal, ~jayshields did mention:
jayshields wrote:I just want the pattern to match number number slash number number slash number number.
I think you though of putting a + behind \d instead of *....he has to check ranges of days and month...

Posted: Fri Feb 10, 2006 12:29 pm
by pickle
Yep - my bad. Original post edited.

EDITED: Corrected errors...

Posted: Fri Feb 10, 2006 1:07 pm
by raghavan20
this may help...

Code: Select all

<pre>
<?php
error_reporting(E_ALL);

$inputString = "01/12/98";
echo preg_match("#[0-9]{2}[/-][0-9]{2}[/-][0-9]{2}#", $inputString);

$inputString = "01/1/98";
echo preg_match("#[0-9]{2}[/-][0-9]{2}[/-][0-9]{2}#", $inputString);

validateDate("01/1/98");
validateDate("13/13/98");
validateDate("29/02/98");
validateDate("31/11/98");
validateDate("30/12/98");
validateDate("29/2/04");

function validateDate($inputString){
$valid = FALSE;
$result = preg_match("#[0-9]{1,2}[/-][0-9]{1,2}[/-][0-9]{1,2}#", $inputString);
if ($result === 1){
	list($day, $month, $year) = split ("[/-]", $inputString);
	
	if ($month <= 12 && $month >= 1){
		if ($month == 2){
			$febDays = ($year%4 == 0)? 29: 28;
			//DEBUG//echo "febDays - $febDays";
			if ($day <= $febDays  && $day >= 1) $valid = TRUE;
		}else if ($month == 1 || $month == 3 || $month == 5 || $month == 7 || $month == 8 || $month == 10 || $month == 12){
			if ($day <= 31 && $day >= 1) $valid = TRUE;
		}else{
			if ($day <= 30 && $day >= 1) $valid = TRUE;
		}
	}
}

echo "<br />". $day, $month, $year."-";
echo ($valid === TRUE)?"Valid ":"Invalid ". "date!!!";

}
?> 
</pre>
EDIT: Output...

Code: Select all

10
01198-Valid
131398-Invalid date!!!
290298-Invalid date!!!
311198-Invalid date!!!
301298-Valid
29204-Valid

Posted: Fri Feb 10, 2006 1:31 pm
by feyd
raghavan20:

split() uses ereg, which you should remember is slow. I'd suggest using preg_split();

your leap year determination is..buggy.

Code: Select all

(($year % 4) == 0 and ($year % 100) != 0) || (($year % 400) == 0 and ($year % 4000) != 0)
is far more accurate.

A month cannot be 1, 3, 5, etc at the same time. Switch the && to ||. Or better yet, use a switch statement for the month length culling.

Posted: Fri Feb 10, 2006 1:39 pm
by raghavan20
feyd wrote:raghavan20:

split() uses ereg, which you should remember is slow. I'd suggest using preg_split();

your leap year determination is..buggy.

Code: Select all

(($year % 4) == 0 and ($year % 100) != 0) || (($year % 400) == 0 and ($year % 4000) != 0)
is far more accurate.

A month cannot be 1, 3, 5, etc at the same time. Switch the && to ||. Or better yet, use a switch statement for the month length culling.
thanks for that extra information on split...

i know that was not the perfect way to calculate the leap year,,,but I expected him to make it better..

that if condition...i somehow wrongly typed it...sorry..

Posted: Fri Feb 10, 2006 2:44 pm
by timvw
The following class accepts a couple of input/output formats... http://www.tonymarston.co.uk/php-mysql/ ... .class.inc