Подтвердить что ты не робот

Правильно определите, является ли строка даты допустимой датой в этом формате

Я получаю строку даты из API и отформатирован как yyyy-mm-dd.

В настоящее время я использую регулярное выражение для проверки строкового формата, который работает нормально, но я вижу некоторые случаи, когда он может быть правильным форматом в соответствии с строкой, но фактически недействительной датой. т.е. 2013-13-01, например.

Есть ли лучший способ в PHP взять строку, такую ​​как 2013-13-01, и указать, является ли она допустимой датой или нет для формата yyyy-mm-dd?

4b9b3361

Ответ 1

Вы можете использовать класс DateTime для этой цели:

function validateDate($date, $format = 'Y-m-d')
{
    $d = DateTime::createFromFormat($format, $date);
    // The Y ( 4 digits year ) returns TRUE for any integer with any number of digits so changing the comparison from == to === fixes the issue.
    return $d && $d->format($format) === $date;
}

[Функция взята из этого ответа.Также на php.net.Первоначально написано Главич.]


Тестовые случаи:

var_dump(validateDate('2013-13-01'));  // false
var_dump(validateDate('20132-13-01')); // false
var_dump(validateDate('2013-11-32'));  // false
var_dump(validateDate('2012-2-25'));   // false
var_dump(validateDate('2013-12-01'));  // true
var_dump(validateDate('1970-12-01'));  // true
var_dump(validateDate('2012-02-29'));  // true
var_dump(validateDate('2012', 'Y'));   // true
var_dump(validateDate('12012', 'Y'));  // false

Демо!

Ответ 2

Определите, является ли какая-либо строка датой

function checkIsAValidDate($myDateString){
    return (bool)strtotime($myDateString);
}

Ответ 3

Использовать простым способом с помощью предварительно созданной функции php:

function checkmydate($date) {
  $tempDate = explode('-', $date);
  // checkdate(month, day, year)
  return checkdate($tempDate[1], $tempDate[2], $tempDate[0]);
}

Test

   checkmydate('2015-12-01'); //true
   checkmydate('2015-14-04'); //false

Ответ 4

Определить, является ли строка датой, даже если строка является нестандартным форматом

(strtotime не принимает пользовательский формат)

<?php
function validateDateTime($dateStr, $format)
{
    date_default_timezone_set('UTC');
    $date = DateTime::createFromFormat($format, $dateStr);
    return $date && ($date->format($format) === $dateStr);
}

// These return true
validateDateTime('2001-03-10 17:16:18', 'Y-m-d H:i:s');
validateDateTime('2001-03-10', 'Y-m-d');
validateDateTime('2001', 'Y');
validateDateTime('Mon', 'D');
validateDateTime('March 10, 2001, 5:16 pm', 'F j, Y, g:i a');
validateDateTime('March 10, 2001, 5:16 pm', 'F j, Y, g:i a');
validateDateTime('03.10.01', 'm.d.y');
validateDateTime('10, 3, 2001', 'j, n, Y');
validateDateTime('20010310', 'Ymd');
validateDateTime('05-16-18, 10-03-01', 'h-i-s, j-m-y');
validateDateTime('Monday 8th of August 2005 03:12:46 PM', 'l jS \of F Y h:i:s A');
validateDateTime('Wed, 25 Sep 2013 15:28:57', 'D, d M Y H:i:s');
validateDateTime('17:03:18 is the time', 'H:m:s \i\s \t\h\e \t\i\m\e');
validateDateTime('17:16:18', 'H:i:s');

// These return false
validateDateTime('2001-03-10 17:16:18', 'Y-m-D H:i:s');
validateDateTime('2001', 'm');
validateDateTime('Mon', 'D-m-y');
validateDateTime('Mon', 'D-m-y');
validateDateTime('2001-13-04', 'Y-m-d');

Ответ 5

Этот параметр не только прост, но и принимает практически любой формат, хотя с нестандартными форматами он может быть неисправен.

$timestamp = strtotime($date);
return $timestamp ? $date : null;

Ответ 6

Вы также можете проанализировать дату месяца и года, а затем вы можете использовать функцию PHP checkdate(), которую вы можете прочитать здесь: http://php.net/manual/en/function.checkdate.php

Вы также можете попробовать следующее:

$date="2013-13-01";

if (preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$date))
    {
        echo 'Date is valid';
    }else{
        echo 'Date is invalid';
    }

Ответ 7

Соглашаясь с cl-sah ответом, но этот звук лучше, короче...

function checkmydate($date) {
  $tempDate = explode('-', $date);
  return checkdate($tempDate[1], $tempDate[2], $tempDate[0]);
}

Тест

checkmydate('2015-12-01');//true
checkmydate('2015-14-04');//false

Ответ 8

У меня есть эта вещь, которая даже с PHP мне нравится находить функциональные решения. Так, например, ответ, данный @migli, действительно хороший, очень гибкий и элегантный.

Но у него есть проблема: что делать, если вам нужно проверить много строк DateTime в том же формате? Вам нужно будет повторить формат повсюду, что противоречит принципу DRY. Мы могли бы поместить формат в константу, но все же нам пришлось бы передавать константу в качестве аргумента для каждого вызова функции.

Но больше не бойся! Мы можем использовать currying для спасения! PHP не делает эту задачу приятной, но по-прежнему можно реализовать currying с PHP:

<?php
function validateDateTime($format)
{
    return function($dateStr) use ($format) {
        $date = DateTime::createFromFormat($format, $dateStr);
        return $date && $date->format($format) === $dateStr;
    };
}

Итак, что мы только что сделали? В основном мы завернули тело функции анонимным и вернули такую ​​функцию. Мы можем вызвать функцию проверки следующим образом:

validateDateTime('Y-m-d H:i:s')('2017-02-06 17:07:11'); // true

Да, не большая разница... но реальная сила исходит от частично примененной функции, сделанной путем currying:

// Get a partially applied function
$validate = validateDateTime('Y-m-d H:i:s');

// Now you can use it everywhere, without repeating the format!
$validate('2017-02-06 17:09:31'); // true
$validate('1999-03-31 07:07:07'); // true
$validate('13-2-4 3:2:45'); // false

Функциональное программирование FTW!

Ответ 9

Как насчет этого?

Мы просто используем блок try-catch.

$dateTime = 'an invalid datetime';

try {
    $dateTimeObject = new DateTime($dateTime);
} catch (Exception $exc) {
    echo 'Do something with an invalid DateTime';
}

Этот подход не ограничивается только одним форматом даты/времени, и вам не нужно определять какую-либо функцию.

Ответ 10

Самый простой способ проверить, действительно ли заданная дата действительна, вероятно, преобразуя ее в unixtime с помощью strtotime, форматируя ее до заданного формата даты, а затем сравнивая ее:

function isValidDate($date) { return date('Y-m-d', strtotime($date)) === $date; }

Конечно, вы можете использовать регулярное выражение для проверки достоверности, но оно будет ограничено заданным форматом, каждый раз вам придется редактировать его, чтобы удовлетворить другие форматы, а также это будет более чем необходимо. Встроенные функции - лучший способ (в большинстве случаев) для достижения заданий.

Ответ 11

Протестированное решение Regex:

    function isValidDate($date)
    {
            if (preg_match("/^(((((1[26]|2[048])00)|[12]\d([2468][048]|[13579][26]|0[48]))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|[12]\d))))|((([12]\d([02468][1235679]|[13579][01345789]))|((1[1345789]|2[1235679])00))-((((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30)))|(02-(0[1-9]|1\d|2[0-8])))))$/", $date)) {
                    return $date;
            }
            return null;
    }

Это вернет null, если дата недействительна или не имеет формат yyyy-mm-dd, иначе она вернет дату.

Ответ 12

/*********************************************************************************
Returns TRUE if the input parameter is a valid date string in "YYYY-MM-DD" format (aka "MySQL date format")
The date separator can be only the '-' character.
*********************************************************************************/
function isMysqlDate($yyyymmdd)
{
    return checkdate(substr($yyyymmdd, 5, 2), substr($yyyymmdd, 8), substr($yyyymmdd, 0, 4)) 
        && (substr($yyyymmdd, 4, 1) === '-') 
        && (substr($yyyymmdd, 7, 1) === '-');
}

Ответ 13

    /**** date check is a recursive function. it need 3 argument 
    MONTH,DAY,YEAR. ******/

    $always_valid_date = $this->date_check($month,$day,$year);

    private function date_check($month,$day,$year){

        /** checkdate() is a php function that check a date is valid 
        or not. if valid date it return true else false.   **/

        $status = checkdate($month,$day,$year);

        if($status == true){

            $always_valid_date = $year . '-' . $month . '-' . $day;

            return $always_valid_date;

        }else{
            $day = ($day - 1);

            /**recursive call**/

            return $this->date_check($month,$day,$year);
        }

    }

Ответ 14

Попробуйте:

$date = "2017-10-01";


function date_checker($input,$devider){
  $output = false;

  $input = explode($devider, $input);
  $year = $input[0];
  $month = $input[1];
  $day = $input[2];

  if (is_numeric($year) && is_numeric($month) && is_numeric($day)) {
    if (strlen($year) == 4 && strlen($month) == 2 && strlen($day) == 2) {
      $output = true;
    }
  }
  return $output;
}

if (date_checker($date, '-')) {
  echo "The function is working";
}else {
  echo "The function isNOT working";
}

Ответ 15

По словам Амала Мурали,

$d = DateTime::createFromFormat('Y-m-d g:i:s', $date);
$d2 = DateTime::createFromFormat('Y-m-d H:i:s', $date);

if(($d && $d->format('Y-m-d g:i:s') == $date) || ($d2 && $d2->format('Y-m-d H:i:s') == $date))
            {
                return true;
            }
            else 
            {
                return false;
            }