PHP Regex для проверки даты в формате ГГГГ-ММ-ДД

98

Я пытаюсь проверить, указаны ли даты, введенные конечными пользователями, в формате ГГГГ-ММ-ДД. Регулярное выражение никогда не было моей сильной стороной, я продолжаю получать ложное возвращаемое значение для preg_match (), которое я настроил.

Итак, я предполагаю, что испортил регулярное выражение, подробно описанное ниже.

$date="2012-09-12";

if (preg_match("^[0-9]{4}-[0-1][0-9]-[0-3][0-9]$",$date))
    {
        return true;
    }else{
        return false;
    }

Есть предположения?

Cosmicsafari
источник
6
Регулярного выражения недостаточно для проверки даты. После регулярного выражения вы также должны использовать одно из этих двух: date("Y-m-d", strtotime("2012-09-12"))=="2012-09-12";или PHP checkdate ( int $month , int $day , int $year ).
Tiberiu-Ionuț Stan
Я не пытаюсь проверить его на данном этапе, я просто хочу убедиться, что он в формате ГГГГ-ММ-ДД.
cosmicsafari
2
Что может быть лучше для введенного пользователем значения, кроме как сразу после регулярного выражения при отправке формы (чтобы вы могли отобразить ошибку)?
Tiberiu-Ionuț Stan
Справедливо, может спасти заморозку позже.
cosmicsafari

Ответы:

198

Попробуй это.

$date="2012-09-12";

if (preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$date)) {
    return true;
} else {
    return false;
}
Авин Варгезе
источник
18
return (bool)preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$date);
Tiberiu-Ionuț Stan
5
Почему этот ответ отмечен как правильный? Это вернет истину для ряда недопустимых дат, например 30 февраля 2016 г. и 31 сентября 2016 г.
Грэм,
7
Этот вопрос касается того, как проверить формат даты (ГГГГ-ММ-ДД), и ответ, помеченный как принятый, не всегда является лучшим ответом, это просто означает, что он сработал для человека, который спросил, прочтите этот красивый тур: stackoverflow. com / tour .
Stramin
@Graham, старый пост, я знаю, но согласен со Страмином - этот вопрос касается проверки формата, а не фактической проверки даты
treyBake
98

Наверное, лучше использовать для этого другой механизм.

Современное решение с DateTime :

$dt = DateTime::createFromFormat("Y-m-d", $date);
return $dt !== false && !array_sum($dt::getLastErrors());

Это тоже подтверждает ввод: $dt !== false гарантирует, что дата может быть проанализирована с указанным форматом, и array_sumуловка - это краткий способ гарантировать, что PHP не выполняет «сдвиг месяца» (например, считайте, что 32 января - 1 февраля). См. DateTime::getLastErrors()Дополнительную информацию.

Олдскульное решение с explodeиcheckdate :

list($y, $m, $d) = array_pad(explode('-', $date, 3), 3, 0);
return ctype_digit("$y$m$d") && checkdate($m, $d, $y);

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

Недостатком этого подхода является то, что вы должны быть очень осторожны, чтобы отклонить все возможные «плохие» входные данные, не отправляя при этом уведомление ни при каких обстоятельствах. Вот как:

  • explode ограничено возвратом 3 токенов (так что, если ввод "1-2-3-4", $d станет "3-4")
  • ctype_digit используется, чтобы убедиться, что ввод не содержит нечисловых символов (кроме тире)
  • array_padиспользуется (со значением по умолчанию, которое приведет checkdateк сбою), чтобы убедиться, что возвращается достаточное количество элементов, чтобы при вводе «1-2» list()не выводилось уведомление
Джон
источник
+1, всегда пользовался DateTimeи никогда не слышал о checkdate... позор мне.
k102 02
@ k102: DateTimeтоже может это сделать. Я только что закончил конкретизировать ответ, взгляните еще раз, если хотите.
Джон
Глядя на руководство по PHP, похоже, что первое решение будет проверять неполные даты (заполнение недостающих значений с текущей даты).
user2428118
Другая проблема с решением №1: «несуществующие значения переносятся», например, 2001-02-31 становится 2001-03-03. (Хотя OP явно не спрашивал, что это невозможно.)
user2428118
1
@ user2428118: Вы пробовали решение №1 точно так, как указано, или только первую строку? Вы щелкнули ссылку, которую я даю на документацию getLastErrors?
Джон
42

гггг-мм-дд: /^((((19|[2-9]\d)\d{2})\-(0[13578]|1[02])\-(0[1-9]|[12]\d|3[01]))|(((19|[2-9]\d)\d{2})\-(0[13456789]|1[012])\-(0[1-9]|[12]\d|30))|(((19|[2-9]\d)\d{2})\-02\-(0[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))\-02\-29))$/g

гггг / мм / дд: /^((((19|[2-9]\d)\d{2})\/(0[13578]|1[02])\/(0[1-9]|[12]\d|3[01]))|(((19|[2-9]\d)\d{2})\/(0[13456789]|1[012])\/(0[1-9]|[12]\d|30))|(((19|[2-9]\d)\d{2})\/02\/(0[1-9]|1\d|2[0-8]))|(((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))\/02\/29))$/g

мм-дд-гггг: /^(((0[13578]|1[02])\-(0[1-9]|[12]\d|3[01])\-((19|[2-9]\d)\d{2}))|((0[13456789]|1[012])\-(0[1-9]|[12]\d|30)\-((19|[2-9]\d)\d{2}))|(02\-(0[1-9]|1\d|2[0-8])\-((19|[2-9]\d)\d{2}))|(02\-29\-((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/g

мм / дд / гггг: /^(((0[13578]|1[02])\/(0[1-9]|[12]\d|3[01])\/((19|[2-9]\d)\d{2}))|((0[13456789]|1[012])\/(0[1-9]|[12]\d|30)\/((19|[2-9]\d)\d{2}))|(02\/(0[1-9]|1\d|2[0-8])\/((19|[2-9]\d)\d{2}))|(02\/29\/((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/g

дд / мм / гггг: /^(((0[1-9]|[12]\d|3[01])\/(0[13578]|1[02])\/((19|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|30)\/(0[13456789]|1[012])\/((19|[2-9]\d)\d{2}))|((0[1-9]|1\d|2[0-8])\/02\/((19|[2-9]\d)\d{2}))|(29\/02\/((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/g

дд-мм-гггг: /^(((0[1-9]|[12]\d|3[01])\-(0[13578]|1[02])\-((19|[2-9]\d)\d{2}))|((0[1-9]|[12]\d|30)\-(0[13456789]|1[012])\-((19|[2-9]\d)\d{2}))|((0[1-9]|1\d|2[0-8])\-02\-((19|[2-9]\d)\d{2}))|(29\-02\-((1[6-9]|[2-9]\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00))))$/g

Шиджу КП
источник
Вышеупомянутое работает для дат с 1900 по 9999 годы, что требуется большую часть времени и на 74 символа короче, чем моя попытка (в формате гггг-мм-дд). если вам нужны даты до 1900 года, то небольшая настройка ответа Shyju позволит с 1000 года и будет еще на 23 символа короче: ^ ((([1-9] \ d {3}) \ - (0 [13578] | 1 [02]) \ - (0 [1-9] | [12] \ d | 3 [01])) | (((19 | [2-9] \ d) \ d {2}) \ - ( 0 [13456789] | 1 [012]) \ - (0 [1-9] | [12] \ d | 30)) | (([1-9] \ d {3}) \ - 02 \ - (0 [1-9] | 1 \ d | 2 [0-8])) | (([1-9] \ d (0 [48] | [2468] [048] | [13579] [26]) | ( (16 | [2468] [048] | [3579] [26]) 00)) \ - 02 \ -29)) $
Грэм
36

Критерии:

Каждый год, делимый на 4, является високосным, за исключением случаев, когда он делится на 100, если он не делится на 400. Итак:

2004 - leap year - divisible by 4
1900 - not a leap year - divisible by 4, but also divisible by 100
2000 - leap year - divisible by 4, also divisible by 100, but divisible by 400

В феврале 29 дней в високосном году и 28 дней в невисокосном.

30 дней в апреле, июне, сентябре и ноябре

31 день в январе, марте, мае, июле, августе, октябре и декабре

Тест:

Все следующие даты должны пройти проверку:

1976-02-29
2000-02-29
2004-02-29
1999-01-31

Следующие даты не пройдут валидацию:

2015-02-29
2015-04-31
1900-02-29
1999-01-32
2015-02-00

Ассортимент:

Мы будем тестировать даты с 1 января 1000 г. по 31 декабря 2999 г. Технически используемый в настоящее время григорианский календарь вошел в употребление только в 1753 году для Британской империи и в разные годы 1600-х годов для стран Европы, но я не собираюсь беспокоиться об этом.

Регулярное выражение для проверки високосного года:

Годы, кратные 400:

1200|1600|2000|2400|2800
can be shortened to:
(1[26]|2[048])00

if you wanted all years from 1AD to 9999 then this would do it:
(0[48]|[13579][26]|[2468][048])00
if you're happy with accepting 0000 as a valid year then it can be shortened:
([13579][26]|[02468][048])00

Годы, кратные 4:

[12]\d([02468][048]|[13579][26])

Годы, кратные 100:

[12]\d00

Не делится на 100:

[12]\d([1-9]\d|\d[1-9])

Годы, делимые на 100, но не на 400:

((1[1345789])|(2[1235679]))00

Делится на 4, но не на 100:

[12]\d([2468][048]|[13579][26]|0[48])

Високосные годы:

divisible by 400 or (divisible by 4 and not divisible by 100)
((1[26]|2[048])00)|[12]\d([2468][048]|[13579][26]|0[48])

Не делится на 4:

[12]\d([02468][1235679]|[13579][01345789])

Не високосный год:

Not divisible by 4 OR is divisible by 100 but not by 400
([12]\d([02468][1235679]|[13579][01345789]))|(((1[1345789])|(2[1235679]))00)

Действительный месяц и день, кроме февраля (ММ-ДД):

((01|03|05|07|08|10|12)-(0[1-9]|[12]\d|3[01]))|((04|06|09|11)-(0[1-9]|[12]\d|30))
shortened to:
((0[13578]|1[02])-(0[1-9]|[12]\d|3[01]))|((0[469]|11)-(0[1-9]|[12]\d|30))

Февраль с 28 днями:

02-(0[1-9]|1\d|2[0-8])

Февраль с 29 днями:

02-(0[1-9]|[12]\d)

Действительной датой:

(leap year followed by (valid month-day-excluding-february OR 29-day-february)) 
OR
(non leap year followed by (valid month-day-excluding-february OR 28-day-february))

((((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]))))

Итак, у вас есть регулярное выражение для дат между 1 января 1000 и 31 декабря 2999 года в формате ГГГГ-ММ-ДД.

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

Это будет соответствовать всем действительным датам. Если вы хотите, чтобы он был действителен только тогда, когда он содержит только одну дату и ничего больше, оберните его ^( )$так:

^(((((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])))))$

Если вы хотите указать дополнительную дату (например, она может быть пустой или действительной), добавьте ее ^$|в начале, например:

^$|^(((((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])))))$
Грэм
источник
8
Это героическое выражение, и оно очень хорошо объяснено.
эмбиент
Есть ли у вас веские доказательства того, что он будет проходить все допустимые случаи и терпеть неудачу во всех недопустимых случаях?
Md Ashraful Islam,
@Md Ashraful Islam Нет
Грэм
@Graham Хотя нет проблем, мы используем его на нашем веб-сайте. Надеюсь, проблем не возникнет.
Md Ashraful Islam
@Md Ashraful Islam - Мы тоже его используем, и пока у нас не было никаких проблем
Грэм,
18

Сделать это можно так:

if (preg_match("/\d{4}\-\d{2}-\d{2}/", $date)) {
    echo 'true';
} else {
    echo 'false';
}

но вам лучше использовать этот:

$date = DateTime::createFromFormat('Y-m-d', $date);
if ($date) {
    echo $date -> format('Y-m-d');
}

в этом случае вы получите объект, который намного проще в использовании, чем просто строки.

k102
источник
1
Используемая здесь методика dateTime вернет true для такой даты, как 2016-05-44, которая не является реальной датой
nonybrighto
Это не лучший пример, особенно если вы хотите получить дату (Ymd). Пример: 0175-44-19927пройдет.
Аттила Наги,
7

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

$date = "2016-02-21";
$format = "Y-m-d";

if(date($format, strtotime($date)) == date($date)) {
    echo "true";
} else {
    echo "false";
}

Можешь попробовать. Если вы измените дату на 21.02.2016, эхо будет ложным. И если после этого вы измените формат на dmY, эхо будет истинным.

С помощью этого простого кода вы сможете проверить, какой формат даты используется, не проверяя его с помощью регулярного выражения.

Может быть, найдется человек, который проверит это в каждом случае. Но я думаю, что моя идея в целом верна. Мне это кажется логичным.

Micha93
источник
Я не думаю, что вам нужна date () около $ date в строке if. if (date ($ format, strtotime ($ date)) == $ date) - должно быть достаточно
iateadonut
7

Вы можете использовать preg_match с функцией php checkdate

$date  = "2012-10-05";
$split = array();
if (preg_match ("/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/", $date, $split))
{
    return checkdate($split[2], $split[3], $split[1]);
}

return false;
Джонатан Мюллер
источник
return preg_match ("/ ^ ([0-9] {4}) - ([0-9] {2}) - ([0-9] {2}) $ /", $ date, $ split)) && checkdate ($ split [2], $ split [3], $ split [1]);
Tiberiu-Ionuț Stan
5

preg_match нуждается в / или другом символе в качестве разделителя.

preg_match("/^[0-9]{4}-[0-1][0-9]-[0-3][0-9]$/",$date)

вы также должны проверить действительность этой даты, чтобы не получить что-то вроде 9999-19-38

bool checkdate ( int $month , int $day , int $year )
Марианбода
источник
3

Вы также можете сделать это так:

if (DateTime::createFromFormat('Y-m-d', $date)->format('Y-m-d') === $date) {

    // date is correctly formatted and valid, execute some code

}

Это не только проверит формат, но и валидность даты self, так как DateTimeбудут созданы только действительные даты, и это должно соответствовать вводу.

касимир
источник
3

ты можешь использовать

function validateDate($date, $format = 'Y-m-d H:i:s')
{
    $d = DateTime::createFromFormat($format, $date);
    return $d && $d->format($format) == $date;
}

$date="2012-09-12";    
echo validateDate($date, 'Y-m-d'); // true or false
разъем
источник
2

Проверить и подтвердить YYYY-MM-DDдату в одной строке заявления

function isValidDate($date) {
    return preg_match("/^(\d{4})-(\d{1,2})-(\d{1,2})$/", $date, $m)
        ? checkdate(intval($m[2]), intval($m[3]), intval($m[1]))
        : false;
}

Результат будет:

var_dump(isValidDate("2018-01-01")); // bool(true)
var_dump(isValidDate("2018-1-1"));   // bool(true)
var_dump(isValidDate("2018-02-28")); // bool(true)
var_dump(isValidDate("2018-02-30")); // bool(false)

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

"/^(\d{4})-(\d{2})-(\d{2})$/"
Владислав Савчук
источник
1

Если вы хотите сопоставить этот тип даты, используйте:

preg_match("~^\d{4}-\d{2}-\d{2}$~", $date)
ujovlado
источник
1

Это должно сказать вам, действителен ли формат и действительна ли дата ввода.

    $datein = '2012-11-0';

    if(preg_match('/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/', $datein)){
        echo 'good';
    }else{
        echo 'no good';
    }
Kenzo
источник
1

Если это поможет, вот регулярное выражение для формата jnY (год должен быть больше 2018 года):

if (preg_match('/^([1-9]|[1-2][0-9]|[3][0-1])\-([1-9]|[1][0-2])\-(?:20)([1][8-9]|[2-9][0-9])$/', $date)) {
   // Do stuff
}
Филип
источник
1

Формат 1: $ format1 = «2012-12-31»;

Формат 2: $ format2 = «31-12-2012»;

if (preg_match("/^[0-9]{4}-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$format1)) {
    return true;
} else {
    return false;
}

if (preg_match("/^(0[1-9]|[1-2][0-9]|3[0-1])-(0[1-9]|1[0-2])-[0-9]{4}$/",$format2)) {
    return true;
} else {
    return false;
}
Хасиб Камаль
источник
1

Наверное кому-нибудь пригодится:

$patterns = array(
            'Y'           =>'/^[0-9]{4}$/',
            'Y-m'         =>'/^[0-9]{4}(-|\/)([1-9]|0[1-9]|1[0-2])$/',
            'Y-m-d'       =>'/^[0-9]{4}(-|\/)([1-9]|0[1-9]|1[0-2])(-|\/)([1-9]|0[1-9]|[1-2][0-9]|3[0-1])$/',
            'Y-m-d H'     =>'/^[0-9]{4}(-|\/)([1-9]|0[1-9]|1[0-2])(-|\/)([1-9]|0[1-9]|[1-2][0-9]|3[0-1])\s(0|[0-1][0-9]|2[0-4])$/',
            'Y-m-d H:i'   =>'/^[0-9]{4}(-|\/)([1-9]|0[1-9]|1[0-2])(-|\/)([1-9]|0[1-9]|[1-2][0-9]|3[0-1])\s(0|[0-1][0-9]|2[0-4]):?(0|[0-5][0-9]|60)$/',
            'Y-m-d H:i:s' =>'/^[0-9]{4}(-|\/)([1-9]|0[1-9]|1[0-2])(-|\/)([1-9]|0[1-9]|[1-2][0-9]|3[0-1])\s(0|[0-1][0-9]|2[0-4]):?((0|[0-5][0-9]):?(0|[0-5][0-9])|6000|60:00)$/',
        );
echo preg_match($patterns['Y'], '1996'); // true
echo preg_match($patterns['Y'], '19966'); // false
echo preg_match($patterns['Y'], '199z'); // false
echo preg_match($patterns['Y-m'], '1996-0'); // false
echo preg_match($patterns['Y-m'], '1996-09'); // true
echo preg_match($patterns['Y-m'], '1996-1'); // true
echo preg_match($patterns['Y-m'], '1996/1'); // true
echo preg_match($patterns['Y-m'], '1996/12'); // true
echo preg_match($patterns['Y-m'], '1996/13'); // false
echo preg_match($patterns['Y-m-d'], '1996-11-1'); // true
echo preg_match($patterns['Y-m-d'], '1996-11-0'); // false
echo preg_match($patterns['Y-m-d'], '1996-11-32'); // false
echo preg_match($patterns['Y-m-d H'], '1996-11-31 0'); // true
echo preg_match($patterns['Y-m-d H'], '1996-11-31 00'); // true
echo preg_match($patterns['Y-m-d H'], '1996-11-31 24'); // true
echo preg_match($patterns['Y-m-d H'], '1996-11-31 25'); // false
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 2400'); // true
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 24:00'); // true
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 24:59'); // true
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 24:60'); // true
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 24:61'); // false
echo preg_match($patterns['Y-m-d H:i'], '1996-11-31 24:61'); // false
echo preg_match($patterns['Y-m-d H:i:s'], '1996-11-31 24:6000'); // true
echo preg_match($patterns['Y-m-d H:i:s'], '1996-11-31 24:60:00'); // true
echo preg_match($patterns['Y-m-d H:i:s'], '1996-11-31 24:59:59'); // true
echo preg_match($patterns['Y-m-d H:i:s'], '1996-11-31 24:59:60'); // false
echo preg_match($patterns['Y-m-d H:i:s'], '1996-11-31 24:60:01'); // false
Ман Нгуен
источник
'1996-11-31 24:00'); // true, действительно? Более того, иногда в минуте 61 секунда, см .: en.wikipedia.org/wiki/Leap_second
Toto
1

Функция для проверки общего формата даты:

function validateDate($date, $format = 'Y-m-d') {
  $d = DateTime::createFromFormat($format, $date);
  return $d && $d->format($format) == $date;
}

Пример исполнения:

var_dump(validateDate('2021-02-28')); // true
var_dump(validateDate('2021-02-29')); // false
Шарад Павар
источник
Пожалуйста, всегда помещайте свой ответ в контекст, а не просто вставляйте код. Подробнее см. Здесь . Также отредактируйте свой ответ, чтобы он содержал все части кода в блоке уценки
gehbiszumeis
0

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

function checkDate($date)
{
  $regex = '/^' . 
    '(' .

    // Allows years 0000-9999
    '(?:[0-9]{4})' .
    '\-' .

    // Allows 01-12
    '(?:' .
    '(?:01)|(?:02)|(?:03)|(?:04)|(?:05)|(?:06)|(?:07)|(?:08)|(?:09)|(?:10)|' .
    '(?:11)|(?:12)' .
    ')' .
    '\-' .

    // Allows 01-31
    '(?:' .
    '(?:01)|(?:02)|(?:03)|(?:04)|(?:05)|(?:06)|(?:07)|(?:08)|(?:09)|(?:10)|' .
    '(?:11)|(?:12)|(?:13)|(?:14)|(?:15)|(?:16)|(?:17)|(?:18)|(?:19)|(?:20)|' .
    '(?:21)|(?:22)|(?:23)|(?:24)|(?:25)|(?:26)|(?:27)|(?:28)|(?:29)|(?:30)|' .
    '(?:31)' .
    ')' .

    '$/';

  if ( preg_match($regex, $date) ) {
    return true;
  }

  return false;
}

$result = checkDate('2012-09-12');

Лично я бы просто пошел на: /^([0-9]{4}\-([0-9]{2}\-[0-9]{2})$/

Ариан
источник
4
Это регулярное выражение излишне сложно. 0[1-9]|1[0-2]соответствует месяцам 01-12 и 0[1-9]|[12][0-9]|3[01]дням 01-31.
estrar
Извините, пока меня
тошнит
0

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

    preg_match("/^([0-9]{4})-(0[1-9]|1[0-2])-(0[1-9]|[1-2][0-9]|3[0-1])$/",$date)
Pratik Soni
источник
Ваш rgex неправильный, он не будет совпадать, 1980-01-01но будет совпадать2100-02-29
Тото
0

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

    function isValidDate($dt)
    {
        $dtArr = explode('/', $dt);
        if (!empty($dtArr[0]) && !empty($dtArr[1]) && !empty($dtArr[2])) {
            return checkdate((int) $dtArr[0], (int) $dtArr[1], (int) $dtArr[2]);
        } else {
            return false;
        }
    }
Амит Гарг
источник
0

[Если вы используете Symfony 4.1.2, попробуйте это] [1]

  $validDate = explode("-",$request->get('date'));
        if (checkdate(filter_var($validDate[1],FILTER_SANITIZE_NUMBER_INT),filter_var($validDate[0],FILTER_SANITIZE_NUMBER_INT),filter_var($validDate[2],FILTER_SANITIZE_NUMBER_INT))){
            $date = date_create(filter_var($request->get('date'),FILTER_SANITIZE_SPECIAL_CHARS));
        }else{
            return $this->redirectToRoute('YOUR_ROUTE');
        }
ДИДИТ Б
источник
0

Из Laravel 5.7 и формата даты, например: 31.12.2019

function checkDateFormat(string $date): bool
{
    return preg_match("/^(0[1-9]|1[0-2])\/(0[1-9]|[1-2][0-9]|3[0-1])\/[0-9]{4}$/", $date);
}
Мексиденс
источник
0

Я искал «как проверить дату» и нашел это решение. Его старое, но я поделюсь ниже методом, который можно использовать для проверки даты в php,

checkdate('01', '31', '2019')
Парвез Алам
источник