Как определить, является ли значение датой в PHP

Я работаю с массивами значений в PHP. Некоторые из этих значений могут включать дату в различных строковых форматах.

Мне нужно преобразовать даты в нескольких форматах в их числовой эквивалент (отметка времени Unix). Проблема заключается в возможности определить, является ли строка датой.

Использование

if (($timestamp = strtotime($str)) === false)

будет проверять допустимую дату из строки, но как определить, должно ли это значение даже быть подтверждено как дата?

Пример:

$x = {1,2,3,"4","11/12/2009","22/12/2000",true,false};

foreach($x as $value)
{

if(is_bool($value))

if(is_string($value))

if(is_numeric($value))

if(is_date($value)) ?

...

}

Короче говоря, есть ли простой способ проверить, является ли строковое значение датой?

Ответ 1

Короче говоря, есть ли простой способ проверить, является ли строковое значение датой?

Не совсем, видя, что это может быть в произвольном формате.

Если это вообще возможно, я бы отказался от разбора магии strtotime(). Если ему удастся создать действительную дату, штраф. Если это не так, вы получите false.

Будьте готовы к возможности ложных срабатываний, потому что strtotime() анализирует даже такие вещи, как "В прошлую пятницу".

Если strtotime() слишком либеральный для вас, вы можете подумать о создании коллекции форматов даты, которую хотите принять, и запустить PHP 5.3 DateTime:createFromFormat используя каждый из форматов в каждую дату.

Что-то вроде (untested)

$formats = array("d.m.Y", "d/m/Y", "Ymd"); // and so on.....
$dates = array(1,2,3,"4","11/12/2009","22/12/2000",true,false);

foreach ($dates as $input) 
 { 
   foreach ($formats as $format)
    {
      echo "Applying format $format on date $input...<br>";

      $date = DateTime::createFromFormat($format, $input);
      if ($date == false) 
       echo "Failed<br>";
      else
       echo "Success<br>";
    }
 }

Ответ 2

Проблема с Pekka script заключается в том, что дата "2011-30-30" также считается действительной. Это измененная версия.

$formats = array("d.m.Y", "d/m/Y", "Ymd"); // and so on.....
$dates = array(1,2,3,"4","11/12/2009","22/12/2000",true,false);

foreach ($dates as $input) 
 { 
   foreach ($formats as $format)
    {
      echo "Applying format $format on date $input...<br>";

      $date = DateTime::createFromFormat($format, $input);
      if ($date == false || !(date_format($date,$format) == $input) ) 
       echo "Failed<br>";
      else
       echo "Success<br>";
    }
 }

Ответ 3

Экстраполяция из http://au1.php.net/checkdate#113205; просто измените массив $formats на все форматы, которые вы хотите проверить.

public function convertDate($value) {

    $formats = ['M d, Y', 'Y-m-d'];
    foreach($formats as $f) {
        $d = DateTime::createFromFormat($f, $value);
        $is_date = $d && $d->format($f) === $value;

        if ( true == $is_date ) break;
    }

    return $is_date;

}