Web

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

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

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

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

 

Ответ 1

Для этого можно использовать DateTime::createFromFormat():

function validateDate($date, $format = 'Y-m-d') {

    $d = DateTime::createFromFormat($format, $date);

    // Y (4-значный год) возвращает TRUE для любого целого числа с любым количеством цифр, поэтому изменение сравнения с == на === устраняет проблему.

    return $d && $d->format($format) === $date;

}

 Тестовые варианты:

var_dump(validateDate('2020-13-01'));  // false

var_dump(validateDate('20202-13-01')); // false

var_dump(validateDate('2020-11-32'));  // false

var_dump(validateDate('2019-2-25'));   // false

var_dump(validateDate('2020-12-01'));  // true

var_dump(validateDate('1970-12-01'));  // true

var_dump(validateDate('2019-02-29'));  // true

var_dump(validateDate('2019', 'Y'));   // true

var_dump(validateDate('12012', 'Y'));  // false

 

 Ответ 2

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

function checkmydate($date) {

  $tempDate = explode('-', $date);

  // checkdate(month, day, year)

  return checkdate($tempDate[1], $tempDate[2], $tempDate[0]);

}

 Тест:

checkmydate('2015-12-01'); //true

checkmydate('2015-14-04'); //false

 

 

Ответ 3

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

<?php

function validateDateTime($dateStr, $format) {

    date_default_timezone_set('UTC');

    $date = DateTime::createFromFormat($format, $dateStr);

    return $date && ($date->format($format) === $dateStr);

}

// Эти возвращают 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');

// Эти возвращают 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');

 

 

Ответ 4

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

 function isValidDate($date) {

    return date('Y-m-d', strtotime($date)) === $date;

}

 

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

 

Ответ 5

У меня есть одна особенность: даже в PHP мне нравится находить функциональные решения. 

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

Но есть решение. Мы можем использовать керринг! PHP не делает эту задачу простой, но реализовать керринг в 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

Да, разница невелика... но настоящий выигрыш исходит от частично применяемой функции, что стало возможным благодаря керрингу:

// Получение частично примененной функции

$validate = validateDateTime('Y-m-d H:i:s');

// Теперь вы можете использовать его везде, не повторяя проверку на формат!

$validate('2017-02-06 17:09:31'); // true

$validate('1999-03-31 07:07:07'); // true

$validate('13-2-4 3:2:45'); // false

 

  

Ответ 6

Попробуйте это:

$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 "Функция выполнилась успешно";

}else {

  echo "Ошибка при выполнении функции";

}

 

 

Схожие статьи

Web

Почему json_encode возвращает пустую строку

Web

Как вставить массив в базу данных MySQL с помощью PHP

Касперский SSL-сертификат для сайта: почему важно его получить?
Web

Касперский SSL-сертификат для сайта: почему важно его получить?

Что делает руководитель веб-разработки в рамках своей должности?
Web

Что делает руководитель веб-разработки в рамках своей должности?