Date Regex (dd/mm/yy)

Any questions involving matching text strings to patterns - the pattern is called a "regular expression."

Moderator: General Moderators

Post Reply
User avatar
jayshields
DevNet Resident
Posts: 1912
Joined: Mon Aug 22, 2005 12:11 pm
Location: Leeds/Manchester, England

Date Regex (dd/mm/yy)

Post 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!
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post 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..
User avatar
jayshields
DevNet Resident
Posts: 1912
Joined: Mon Aug 22, 2005 12:11 pm
Location: Leeds/Manchester, England

Post by jayshields »

Thanks feyd.

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

Thanks.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post by feyd »

the stickies explain them.
User avatar
raghavan20
DevNet Resident
Posts: 1451
Joined: Sat Jun 11, 2005 6:57 am
Location: London, UK
Contact:

Post by raghavan20 »

but how about a date, "2/2/98" ???
User avatar
pickle
Briney Mod
Posts: 6445
Joined: Mon Jan 19, 2004 6:11 pm
Location: 53.01N x 112.48W
Contact:

Post 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.
Last edited by pickle on Fri Feb 10, 2006 12:29 pm, edited 1 time in total.
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
User avatar
raghavan20
DevNet Resident
Posts: 1451
Joined: Sat Jun 11, 2005 6:57 am
Location: London, UK
Contact:

Post 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...
User avatar
pickle
Briney Mod
Posts: 6445
Joined: Mon Jan 19, 2004 6:11 pm
Location: 53.01N x 112.48W
Contact:

Post by pickle »

Yep - my bad. Original post edited.
Real programmers don't comment their code. If it was hard to write, it should be hard to understand.
User avatar
raghavan20
DevNet Resident
Posts: 1451
Joined: Sat Jun 11, 2005 6:57 am
Location: London, UK
Contact:

EDITED: Corrected errors...

Post 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
Last edited by raghavan20 on Fri Feb 10, 2006 2:35 pm, edited 1 time in total.
User avatar
feyd
Neighborhood Spidermoddy
Posts: 31559
Joined: Mon Mar 29, 2004 3:24 pm
Location: Bothell, Washington, USA

Post 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.
User avatar
raghavan20
DevNet Resident
Posts: 1451
Joined: Sat Jun 11, 2005 6:57 am
Location: London, UK
Contact:

Post 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..
timvw
DevNet Master
Posts: 4897
Joined: Mon Jan 19, 2004 11:11 pm
Location: Leuven, Belgium

Post by timvw »

The following class accepts a couple of input/output formats... http://www.tonymarston.co.uk/php-mysql/ ... .class.inc
Post Reply