Регулярний вираз PHP для перевірки дати має формат РРРР-ММ-ДД


97

Я намагаюся перевірити, чи вказані дати кінцевими користувачами є РРРР-ММ-ДД. Regex ніколи не був моєю сильною стороною, я постійно отримую помилкове значення повернення для 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;
    }

Будь-які думки?


6
Regex недостатньо для підтвердження дати. Після регулярного виразу вам слід також використовувати одне з цих двох: 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

Відповіді:


196

Спробуйте це.

$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.02.2016 та 31.09.2016
Грем

7
Це питання стосується того, як перевірити формат дати (РРРР-ММ-ДД), і відповідь, позначена як прийнята, не завжди є найкращою відповіддю, це просто означає, що вона спрацювала для того, хто запитав, прочитайте цей чудовий тур: stackoverflow. ком / тур .
страмін

@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,

@ k102: DateTimeтакож може це зробити. Я щойно закінчив розбирати відповідь, ще раз подивись, якщо хочеш.
Джон

Дивлячись на посібник PHP, схоже, перше рішення перевірить неповні дати (заповнивши відсутні значення з поточної дати).
user2428118

Ще одна проблема з рішенням №1: "неіснуючі значення перекидаються", наприклад 2001-02-31 стає 2001-03-03. (Хоча ОП явно не запитував, що це неможливо.)
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 року, тоді незначна корекція відповіді Шию дозволить з 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-х рр. Для країн Європи, але я не збираюся турбуйся про це.

Regex для тестування на високосний рік:

Роки, що діляться на 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)

Дійсні місяць і день, крім лютого (MM-DD):

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

7
Це героїчний вираз і дуже добре пояснено.
атмосфера

Чи маєте ви вагомі докази того, що він пройде кожну дійсну справу та провалить кожну недійсну справу?
Md Ashraful Islam

@Md Ashraful Islam No
Грем

@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');
}

у цьому випадку ви отримаєте об'єкт, який набагато простіший у використанні, ніж просто рядки.


1
Метод dateTime, використаний тут, поверне значення для такої дати, як 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, відлуння буде правдою.

За допомогою цього простого коду ви зможете перевірити, який формат дати використовується, не перевіряючи його регулярним виразом.

Можливо, є людина, яка перевірить це на кожному конкретному випадку. Але я думаю, що моя ідея в цілому справедлива. Для мене це здається логічним.


Я не думаю, що вам потрібна дата () навколо $ date у рядку if. if (date ($ format, strtotime ($ date)) == $ date) - повинно бути достатньо
iateadonut

7

Ви можете використовувати preg_match з функцією перевірки дати php

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

повернути preg_match ("/ ^ ([0-9] {4}) - ([0-9] {2}) - ([0-9] {2}) $ /", $ date, $ split)) && дата чека ($ 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

}

Це дозволить перевірити не лише формат, але й дійсність самої дати, оскільки 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)

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';
    }

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
Тото

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

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

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)

Ваш rgex помилковий, він не збігатиметься, 1980-01-01але збігатиметься2100-02-29
Toto

0

Цей метод може бути корисним для перевірки дати в PHP. Поточний метод призначений для формату мм / дд / рррр. Ви повинні оновити порядок опцій в checkdate відповідно з вашим форматом і роздільник вибухає .

    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')
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.