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

Как выполнить запрос «INSERT IF NOT EXIST» в MySQL?

Как создать грамотное оформление страницы 404 на собственном сайте
Web

Как создать грамотное оформление страницы 404 на собственном сайте

Web

Как получить значения функции при вводе значения из PHP формы?

Web

Заголовки запросов Cross-Origin (CORS) с заголовками PHP

×