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

Проверьте, является ли переменная допустимой датой с PHP

Я работаю над script, который будет импортировать некоторые данные из файла CSV. Поскольку я делаю это, я хочу проверить переменную, чтобы увидеть, является ли она допустимой строкой даты.

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

прямо сейчас я использую strtotime(), но это нелегко

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

В этом случае "май" - это имя человека, а не дата вообще.

Может ли кто-нибудь рекомендовать более надежную функцию?

Изменить на основе вопросов от некоторых из вас.

Для переменной, которая будет передаваться как "дата" в моем случае, она должна быть специфичной для дня/месяца/года, поэтому просто "май" будет неопределенным для подсчета.

Основываясь на этом и Pauls хорошей точке ниже, мы также можем проверить, содержит ли строка число, например

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

Это, по-видимому, покрывает мои непосредственные потребности, но может ли кто-нибудь выявить какие-либо проблемы или предложить улучшения?

4b9b3361

Ответ 1

Используйте date_parse и проверьте значения возвращаемого массива

$date = date_parse("May")

// ["year"] == FALSE
// ["month"] == 5
// ["day"] == FALSE

Вы также можете передать их в checkdate.

$date = date_parse($someString);
if ($date["error_count"] == 0 && checkdate($date["month"], $date["day"], $date["year"]))
    echo "Valid date";
else
    echo "Invalid date";

Ответ 2

Я не думаю, что есть все-в-один ответ на эту проблему. У вас может быть другая стратегия в зависимости от вашего варианта использования.

Ваш strtotime() - идеальное решение, но, как вы говорите, вы можете оказаться в ложном позитиве. Зачем? Потому что может быть слово или имя. Однако, что является результатом strtotime('May')?

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

Таким образом, если только месяц вернет дату текущего года и текущего дня, начинающегося в полночь с данным месяцем. Возможным решением было бы проверить, имеет ли ваша строка текущий день и/или текущий год, таким образом, вы можете проверить, чтобы ваша дата была полностью квалифицированной датой и действительна.

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

Простой strpos() или даже регулярное выражение должно делать трюк.

Однако он немного нечетный и должен использоваться только в том случае, если у вас нет другого способа сделать.

Я считаю, что лучшим решением было бы определить набор допустимых форматов и интерполировать результат, чтобы убедиться, что дата действительна.

$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
);

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

В любом случае вам может понадобиться время от времени адаптировать вашу функцию, потому что нет простого способа сделать ее пуленепробиваемой.

Ответ 3

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

function checkInputIsDate($date) {
    return (bool)strpbrk($date,1234567890) && strtotime($date);
}

Это работает, потому что это устраняет проблемы, описанные выше, где только месяц передается в strtotime, убедившись, что в строке есть числа с strpbrk, а также проверка strtotime выводит дату.

И узнал о функции, которую я не знал.

Надеюсь, это поможет кому-то.