Проверьте, является ли переменная допустимой датой с 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";
}
Это, по-видимому, покрывает мои непосредственные потребности, но может ли кто-нибудь выявить какие-либо проблемы или предложить улучшения?
Ответы
Ответ 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
выводит дату.
И узнал о функции, которую я не знал.
Надеюсь, это поможет кому-то.