View Full Version : ereg / preg_match time validation
Schmoopy
03-10-2009, 12:02 AM
Hi, I want to validate the time the user has entered to see whether it's in the correct format (12 hour format).
From googling around I found:
# Returns time in HH:MM[AM|PM] format if it matches, else false
function checkTime($time)
{
return (preg_match('/[\s0]*(\d|1[0-2]):(\d{2})\s*([AaPp][Mm])/xms', $time, $match))
? sprintf('%02d:%d%s', $match[1], $match[2], strtoupper($match[3]))
: false;
}
It almost works, but it allows 21:50pm, I don't have any knowledge of ereg / preg_match so I'm finding it hard to alter it to fix it.
Anyone know what I need to do to fix it? Or come up with a better solution?
Thanks.
techietim
03-10-2009, 01:00 AM
<?php
/*
VALID:
02:57am
12:53PM
INVAID:
2:57am
05:15 PM
13:11Pm
12:00aM
*/
function check_12hour_time($str){
preg_match('/^(0[1-9]|1[0-2]):(0[1-9]|[1-5][0-9])(AM|PM|pm|am)$/', $str, $matches);
return !$matches ? false:array('hours' => $matches[1], 'minutes' => $matches[2], 'tod' => $matches[3]);
}
var_dump(check_12hour_time('11:59PM'));
Schmoopy
03-10-2009, 08:56 AM
That works great, thanks! :)
JasonDFR
03-10-2009, 09:03 AM
<?php
$time = '21:50PM';
// Returns 1 if valid, 0 if not valid, false if $time hasn't been set
function check12Hour($time = null) {
if (!$time)
return false;
return preg_match('/^(0[1-9]|1[0-2]):([0-5][0-9])(AM|PM)$/', $time);
}
echo check12Hour($time);
?>
I'm no expert with regex, but I am slowly getting better.
I think the trick is to build them one step at a time, testing it out as you go.
For example:
Start out with an idea of what valid is. In this case 09:00AM is valid.
Set up the format: '//'
Then go step by step:
'//'
'/^09:00AM$/' // ^ means starts with, $ means ends with
// The first "group" is the first two digits of the time
// Parenthesis around a group
// Now think about all possible values for the first two digits
// You can have a 0 followed by a 1-9 OR a 1 followed by a 0-2
// 0 followed by a 1-9 is written 0[1-9]
// Use | ( the pipe char ) for OR
'/^(0[1-9]|1[0-2]):00AM$/'
// Next you want a single colon, so type that.
// Then move on to the next group
// Parenthesis and follow the same idea as before
'/^(0[1-9]|1[0-2]):([0-5][0-9])AM$/'
// Then the AM OR PM gets some parenthesis
'/^(0[1-9]|1[0-2]):([0-5][0-9])(AM|PM)$/'
// And that's it
'/
JasonDFR
03-10-2009, 09:19 AM
On yeah, one more thing I forgot to mention. If you are programming PHP forget you ever heard about ereg.
Schmoopy
03-10-2009, 09:34 AM
@techietim - Your function almost worked :p, but didn't allow times like 05:00pm, or just any time with 2 0s for the minutes.
@JasonDFR - Thanks for your explanation, I've tested all my extremes and different values and so far all have passed, lucky you replied too :)
Thanks to both of you. Kudos.
[edit] And yes I did hear that ereg was being replaced by preg_match, since it's much faster and something else I can't remember, I only use it because I'm not very good at matches but I should spend some more time learning patterns as it seems really important when it comes to good validation.
JasonDFR
03-10-2009, 09:39 AM
Cool,
I'm confident the function I posted will work for you.
I realized techie didn't quite get it right. His problem was (0[1-9]|[1-5][0-9]) which would be ok for 01 - 09 OR 10 - 59, but not 00.
I'm not sure why he did that. What was your thinking Techie?
techietim
03-10-2009, 10:19 AM
I'm not sure why he did that. What was your thinking Techie?
Whoops :p
I was half asleep when I wrote that, so please excuse me.
JasonDFR
03-10-2009, 10:23 AM
hehe, No worries. That kinda thing happens to me when I'm wide awake.
Schmoopy
03-10-2009, 10:30 AM
Still guys, thanks for helping out - I'm getting so confused here converting 12 hour time to 24 hour for the database and then converting it back again for the user xD
JasonDFR
03-10-2009, 10:50 AM
<?php
// Try this out:
echo ( date("H:i:s", strtotime("3:30 pm")) );
// MySQL query will select the time in 24 HOUR format and return it in 12 HOUR
$q = "SELECT TIME_FORMAT(time_column, '%r') as time FROM table WHERE ..." ;
Schmoopy
03-10-2009, 11:55 AM
Thanks for that, but I'd already made the necessary functions...
But while we're on the topic of validation I've made a function to validate the date as well, it works just as intended but I want to know how to return an error if the date is false.
Like : 31/04/2009 - Passes my preg_match() function as it is valid
But 31/04/2009 is not actually valid, and if you insert it into a database it truncates and ends up with 0000-00-00.
I tried the following to catch the error, but having no luck - any suggestions?
// Insert date into empty row to test it is a valid date, e.g. User could input 31/04/2009 which passes the RegExp but is not a valid date
#MySQL error 1265 is output if data truncated
$query = "INSERT INTO appointments (`date`) VALUES('$date')";
if(mysql_query($query))
{
if(mysql_errno() == 1265)
{
die("Invalid date.");
}
}
JasonDFR
03-10-2009, 12:18 PM
http://www.php.net/manual/en/function.checkdate.php
JasonDFR
03-10-2009, 12:20 PM
Thanks for that, but I'd already made the necessary functions..
If you made functions for this, you shouldn't have. PHP and MySQL already have functions for this. That is what I posted above.
Just like checkdate() .
Schmoopy
03-10-2009, 11:25 PM
Ah I see, checkdate's very helpful - but I think it's better that I've made my own functions, as I'm doing it for my A2 coursework, so will hopefully get more marks :)
JasonDFR
03-11-2009, 06:15 AM
Ah I see, checkdate's very helpful - but I think it's better that I've made my own functions, as I'm doing it for my A2 coursework, so will hopefully get more marks :)
Ahh, I see. Hopefully you are right !
Powered by vBulletin® Version 4.2.2 Copyright © 2021 vBulletin Solutions, Inc. All rights reserved.