Php date validation question

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

dagee
Forum Commoner
Posts: 33
Joined: Thu Oct 19, 2006 8:31 pm

Php date validation question

Post by dagee »

Hi,

I am having a bit of a problem with a program that I wrote and I was hoping someone could give me some ideas (or point me in the right direction).

Currently I have a program that asks the user to enter in a date in a text field. While I have specified that users enter in their dates as the following (mm/dd/yyyy), the problem is some people are not doing that ( I have gottten mm/dd/yy and also mm.dd.yy and other various permutations of this date format. So either I need to bring up an error message when the user enters the date in an improper format or I have to convert the date string such that no matter how the user enters the date (assuming month/ day / year) the string is still seen as mm/dd/yyyy

Any nudges in the right direction would be a huge help. As always thanks in advance for your help.
Last edited by dagee on Thu Oct 26, 2006 7:45 pm, edited 1 time in total.
User avatar
s.dot
Tranquility In Moderation
Posts: 5001
Joined: Sun Feb 06, 2005 7:18 pm
Location: Indiana

Post by s.dot »

Have 3 select boxes.

Month - January through December
Day - 1 through 31
Year - your choice on that one
Set Search Time - A google chrome extension. When you search only results from the past year (or set time period) are displayed. Helps tremendously when using new technologies to avoid outdated results.
User avatar
Cameri
Forum Commoner
Posts: 87
Joined: Tue Apr 12, 2005 4:12 pm
Location: Santo Domingo, Dominican Republic

Post by Cameri »

Or, get yourself a nifty calendar popup window from where users can choose from :P. :wink:
dagee
Forum Commoner
Posts: 33
Joined: Thu Oct 19, 2006 8:31 pm

strtotime

Post by dagee »

I used the strtotime function and that took care of some of the problems but it still cannot deal if the user enters mm.dd.yyyy (uses periods). I don't mind this as a solution (unless there is someother problem with this solution) but... is there a way to make strtotime recognize mm.dd.yyyy as the same as mm/dd/yyyy? Or is this not a good solution and I should force the user to enter the data correctly?
angelena
Forum Commoner
Posts: 53
Joined: Mon Nov 22, 2004 4:10 am

Post by angelena »

Assuming the date is assign to a variable $inputted_date

Code: Select all

if (strstr($inputted_date, "/") )   // able to find the occurence of  first '/'
{

    $date_array = explode("/", $inputted_date);
    .. perform check on the value of each array...

}
else
{

    ... your error message goes here
}
User avatar
Luke
The Ninja Space Mod
Posts: 6424
Joined: Fri Aug 05, 2005 1:53 pm
Location: Paradise, CA

Post by Luke »

I don't remember where I got this for sure... but it validates a date. If you have any questions on implementations, feel free to ask.

Code: Select all

function isMMDDYY($input, $sep='/') {
       
                $pattern = '/^(\\d{2})'.$sep.'(\\d{2})'.$sep.'(\\d{2})$/';
                if (!preg_match($pattern, $input, $matches)) {
               
                        return false;
                       
                } else {
               
                        if (in_array($matches[1], self::$m30)) {
                                if ($matches[2] > 30 || $matches[2] < 1) return false;
                                return true;
                        } elseif (in_array($matches[1], self::$m31)) {
                                if ($matches[2] > 31 || $matches[2] < 1) return false;
                                return true;
                        } elseif ($matches[1] == self::$m28) {
                                if ($matches[2] > 29 || $matches[2] < 1) return false;
                                return true;
                        } else {
                                return false;
                        }
               
                } //End if
       
        }
jmut
Forum Regular
Posts: 945
Joined: Tue Jul 05, 2005 3:54 am
Location: Sofia, Bulgaria
Contact:

Post by jmut »

The Ninja Space Goat wrote:I don't remember where I got this for sure... but it validates a date. If you have any questions on implementations, feel free to ask.

Code: Select all

function isMMDDYY($input, $sep='/') {
       
                $pattern = '/^(\\d{2})'.$sep.'(\\d{2})'.$sep.'(\\d{2})$/';
                if (!preg_match($pattern, $input, $matches)) {
               
                        return false;
                       
                } else {
               
                        if (in_array($matches[1], self::$m30)) {
                                if ($matches[2] > 30 || $matches[2] < 1) return false;
                                return true;
                        } elseif (in_array($matches[1], self::$m31)) {
                                if ($matches[2] > 31 || $matches[2] < 1) return false;
                                return true;
                        } elseif ($matches[1] == self::$m28) {
                                if ($matches[2] > 29 || $matches[2] < 1) return false;
                                return true;
                        } else {
                                return false;
                        }
               
                } //End if
       
        }
what exactly behind self::$m30,self::$m31, self::$m29 ?
User avatar
Luke
The Ninja Space Mod
Posts: 6424
Joined: Fri Aug 05, 2005 1:53 pm
Location: Paradise, CA

Post by Luke »

oh... haha sorry... I just pulled it out of a class that called the method statically... so I assumed it didn't need any other part of the class... here:

Code: Select all

function isMMDDYY($input, $sep='/') {
       
         $m30 = array (
                '04',
                '06',
                '09',
                '11'
        );
       
        $m31 = array (
                '01',
                '03',
                '05',
                '07',
                '08',
                '10',
                '12'
        );
       
        $m28 = '02';
       
        $months = array (
                'JAN' => '01',
                'FEB' => '02',
                'MAR' => '03',
                'APR' => '04',
                'MAY' => '05',
                'JUN' => '06',
                'JUL' => '07',
                'AUG' => '08',
                'SEP' => '09',
                'OCT' => '10',
                'NOV' => '11',
                'DEC' => '12'
        );
                $pattern = '/^(\\d{2})'.$sep.'(\\d{2})'.$sep.'(\\d{2})$/';
                if (!preg_match($pattern, $input, $matches)) {
               
                        return false;
                       
                } else {
               
                        if (in_array($matches[1], $m30)) {
                                if ($matches[2] > 30 || $matches[2] < 1) return false;
                                return true;
                        } elseif (in_array($matches[1], $m31)) {
                                if ($matches[2] > 31 || $matches[2] < 1) return false;
                                return true;
                        } elseif ($matches[1] == $m28) {
                                if ($matches[2] > 29 || $matches[2] < 1) return false;
                                return true;
                        } else {
                                return false;
                        }
               
                } //End if
       
        }
User avatar
RobertGonzalez
Site Administrator
Posts: 14293
Joined: Tue Sep 09, 2003 6:04 pm
Location: Fremont, CA, USA

Post by RobertGonzalez »

scottayy wrote:Have 3 select boxes.

Month - January through December
Day - 1 through 31
Year - your choice on that one
I like this idea the best. That way you always know you are getting the right data for the right segment of the date, then you build the date into a string the way you want it (so if you change how you handle dates later, it is easily fixed in one place).
jmut
Forum Regular
Posts: 945
Joined: Tue Jul 05, 2005 3:54 am
Location: Sofia, Bulgaria
Contact:

Post by jmut »

Everah wrote:
scottayy wrote:Have 3 select boxes.

Month - January through December
Day - 1 through 31
Year - your choice on that one
I like this idea the best. That way you always know you are getting the right data for the right segment of the date, then you build the date into a string the way you want it (so if you change how you handle dates later, it is easily fixed in one place).
no really. form data could always be spoofed. select dropdown is not an exception.
wyrmmage
Forum Commoner
Posts: 56
Joined: Sat Oct 28, 2006 12:43 pm
Location: boise, ID

Post by wyrmmage »

jmut wrote:
Everah wrote:
scottayy wrote:Have 3 select boxes.

Month - January through December
Day - 1 through 31
Year - your choice on that one
I like this idea the best. That way you always know you are getting the right data for the right segment of the date, then you build the date into a string the way you want it (so if you change how you handle dates later, it is easily fixed in one place).
no really. form data could always be spoofed. select dropdown is not an exception.
Ya, make sure that you still validate the date if you use this method so your script will not crash if someone spoofs the input.
User avatar
RobertGonzalez
Site Administrator
Posts: 14293
Joined: Tue Sep 09, 2003 6:04 pm
Location: Fremont, CA, USA

Post by RobertGonzalez »

Yes, form data can be spoofed, but tell me validating three parts of a date that are already separated for your is not easier than separating a string by God knows what character in God knows what order, then validating those pieces?
dagee
Forum Commoner
Posts: 33
Joined: Thu Oct 19, 2006 8:31 pm

Wow so many ways to take care of this problem- awesome

Post by dagee »

Right now I am still using the strtotime function to handle different format dates. In looking at the text file that hold all the date data it looks like this method will deal with 97% of the errors. Tie in with that method angelina mentioned for taking care of dd.mm.yy (using period instead of slashes) and I would think I am golden. But in all honesty, I have really no experience with this so perahps I am overlooking user errors. I had originally thought of creating three drop down menus as someone mentioned earlier in this thread but decided that my users should be able to follow some basic date format instructions (I was wrong).

For those who have experience with date validation and dealing with invalid user input, do you think using the method I have outlined above would be a good solution? Or should I be more controlling in how the user's input data.

Again, thank you so much for all the ideas here. Just in reading this thread I picked up a couple really cool ideas I had not had before not to mention being introduced some functions that I had never seen before but I will definitely use. You guys are awesome.

Dag
User avatar
RobertGonzalez
Site Administrator
Posts: 14293
Joined: Tue Sep 09, 2003 6:04 pm
Location: Fremont, CA, USA

Re: Wow so many ways to take care of this problem- awesome

Post by RobertGonzalez »

dagee wrote:I had originally thought of creating three drop down menus as someone mentioned earlier in this thread but decided that my users should be able to follow some basic date format instructions (I was wrong).
I tend to err on the side of 'never trust user input'. There is no reason why a user can't select a series of drop downs to build a date. Then you can actually control (form the most part) what the user sees and what 99% of your users will use. Then, for validating, you can use strlen(), is_numeric(), and range() to determine if the passed information is adequate. If it is, continue building the date, if is not, error out.
User avatar
ambivalent
Forum Contributor
Posts: 173
Joined: Thu Apr 14, 2005 8:58 pm
Location: Toronto, ON

Post by ambivalent »

What about checkdate()?
Post Reply