Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Check if variable is a valid date with PHP

I am working on a script that will import some data from a CSV file. As I am doing this I want to be able to check a variable to see if it is a valid date string.

I have seen several ways to check if a sting is a date, but most of them require you to now the format. I will not know the format that the date will in.

right now I am using strtotime(), but this fails to easily

$field ="May"; if(strtotime($field)){     echo "This is a date"; } 

In this case, "May" was the persons first name, and not a date at all.

Can any one recommend more reliable function?

Edit based on questions from some of you.

For a variable to pass as a "date" in my case, it would need to be specific to a day/month/year, so just "May" would be to vague to count.

Based on that and Pauls good point below we can also test to see if the string contains a number, such as

$field ="May"; if(strtotime($field) && 1 === preg_match('~[0-9]~', $field)){     echo "This is a date"; }else{     echo "Nope not a date"; } 

This seems to cover my immediate needs, but can any one spot any issues or suggest improvements?

like image 418
Alex Avatar asked May 21 '12 20:05

Alex


People also ask

How do you check if a date is valid in PHP?

In order to check if a string is a date or not, you can use the strtotime() method. Note: The strtotime() method functions by parsing an English datetime string into a UNIX timestamp.

How do you check if a variable is a date?

You can use the ! isNaN() function to check whether a date is valid. If x is a Date, isNaN(x) is equivalent to Number.

What does date () do in PHP?

The date function in PHP is used to format the timestamp into a human desired format. The timestamp is the number of seconds between the current time and 1st January, 1970 00:00:00 GMT. It is also known as the UNIX timestamp.

What is Strtotime PHP?

The strtotime() function parses an English textual datetime into a Unix timestamp (the number of seconds since January 1 1970 00:00:00 GMT). Note: If the year is specified in a two-digit format, values between 0-69 are mapped to 2000-2069 and values between 70-100 are mapped to 1970-2000.


2 Answers

Use date_parse and check the values of the returned array

$date = date_parse("May")  // ["year"] == FALSE // ["month"] == 5 // ["day"] == FALSE 

You can also pass those into checkdate.

$date = date_parse($someString); if ($date["error_count"] == 0 && checkdate($date["month"], $date["day"], $date["year"]))     echo "Valid date"; else     echo "Invalid date"; 
like image 117
saluce Avatar answered Oct 21 '22 22:10

saluce


I don't think there is a all-in-one answer to this problem. You may have different strategy depending on your use case.

Your strtotime() is a perfect solution, but as you say, you may end up with false positive. Why? Because may may be a word or a name. However, what is the result of strtotime('May')?

echo date(DateTime::ISO8601, strtotime('May')); 2012-05-21T00:00:00+0200 

So giving only the month will return a date of the current year and the current day starting at midnight with the given month. A possible solution would be to check if your string has the current day and/or the current year included, this way, you may check against to make sure your date is a fully qualified date and valid.

echo date(DateTime::ISO8601, strtotime('May Day')); // (strtotime() returns false) 1970-01-01T01:00:00+0100  echo date(DateTime::ISO8601, strtotime('May 21')); 2012-05-21T00:00:00+0200 

A simple strpos() or even a regex should do the trick.

However it is a bit odd and should be used only if you have no other way to do.

I believe that a better solution would be to define a set of valid format and interpolate the result to make sure that the date is valid.

$validDateFormatPatterns = array(  '[0-9]{1,2}-[0-9]{1,2}-[0-9]{4}', // 21-05-2012, obviously this pattern is simple and would accept 05-21-2012,  'the [0-9]{1,2}(th|st|nd|rd) (January|February|...|May|...|December) [0,9]{4}', // The 21st May 2012 ); 

You should try to cover most of the case and I'm sure you will be able to find regex that checks for most current date format.

In any case, you may need to adapt your function from time to time because there is no easy way to make it bulletproof.

like image 45
Boris Guéry Avatar answered Oct 21 '22 21:10

Boris Guéry