エンドユーザーが入力した日付がYYYY-MM-DDであることを確認しようとしています。 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;
}
何かご意見は?
これを試して。
$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;
}
これには別のメカニズムを使用することをお勧めします。
DateTime
を使用した最新のソリューション
$dt = DateTime::createFromFormat("Y-m-d", $date);
return $dt !== false && !array_sum($dt::getLastErrors());
これにより、入力も検証されます。$dt !== false
は、指定された形式で日付を解析できることを保証し、array_sum
トリックは、PHPが「月シフト」を行わなかったことを保証する簡潔な方法です(たとえば、1月32日が2月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);
これにより、入力が有効な日付であることも検証されます。もちろん正規表現を使用してそれを行うことができますが、それはさらに大騒ぎになるでしょう-2月29日は正規表現で検証することはできません。
このアプローチの欠点は、どのような状況でも通知を出さずに、考えられるすべての「悪い」入力を拒否するように非常に注意しなければならないことです。方法は次のとおりです。
explode
は3つのトークンを返すように制限されています(入力が「1-2-3-4」の場合、$d
は「3-4」になります)ctype_digit
は、入力に数字以外の文字が含まれないようにするために使用されます(ダッシュを除く)array_pad
を(checkdate
が失敗するデフォルト値で)使用して、入力が「1-2」の場合にlist()
が通知を出さないように十分な要素が返されるようにします。yyyy-mm-dd:/^((((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
yyyy/mm/dd:/^((((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
mm-dd-yyyy:/^(((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
mm/dd/yyyy:/^(((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
dd/mm/yyyy:/^(((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
dd-mm-yyyy:/^(((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
基準:
毎年4で割り切れる年はうるう年ですが、400で割り切れない限り100で割り切れる場合を除きます。
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
2月はうるう年で29日、うるう年でない場合は28日です。
4月、6月、9月、11月の30日間
1月、3月、5月、7月、8月、10月、12月の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
範囲:
1000年1月1日から2999年12月31日までの日付をテストします。技術的には、現在使用されているグレゴリオ暦は、大英帝国では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])
400でなく100で割り切れる年:
((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])
Le年ではない:
Not divisible by 4 OR is divisible by 100 but not by 400
([12]\d([02468][1235679]|[13579][01345789]))|(((1[1345789])|(2[1235679]))00)
2月(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))
2月と28日:
02-(0[1-9]|1\d|2[0-8])
2月と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]))))
YYYY-MM-DD形式の1000年1月1日から2999年12月31日までの日付の正規表現があります。
かなり短縮できると思いますが、他の人に任せるつもりです。
これはすべての有効な日付に一致します。日付が1つだけで、他に何も含まれていない場合にのみ有効にする場合は、次のように^( )$
でラップします。
^(((((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])))))$
このようにすることができます:
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');
}
この場合、単なる文字列よりも使いやすいオブジェクトを取得します。
Checkdate php関数でpreg_matchを使用できます
$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;
これは古い質問です。しかし、私は良い解決策があると思います。
$date = "2016-02-21";
$format = "Y-m-d";
if(date($format, strtotime($date)) == date($date)) {
echo "true";
} else {
echo "false";
}
あなたはそれを試すことができます。日付を2016年2月21日に変更すると、エコーは偽になります。その後、形式をd.m.Yに変更すると、エコーはtrueになります。
この簡単なコードを使用すると、正規表現でチェックすることなく、使用されている日付形式をチェックできるはずです。
たぶん、すべてのケースでそれをテストする人がいます。しかし、私の考えは一般的に有効だと思います。私にとっては論理的なようです。
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 )
使用できます
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
次のようにすることもできます。
if (DateTime::createFromFormat('Y-m-d', $date)->format('Y-m-d') === $date) {
// date is correctly formatted and valid, execute some code
}
DateTime
は有効な日付のみを作成し、入力と一致する必要があるため、これは形式だけでなく日付selfの有効性もチェックします。
1行のステートメントで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})$/"
これにより、形式が有効かどうか、および入力日付が有効かどうかがわかります。
$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';
}
助けになる場合は、j-n-Y形式の正規表現を以下に示します(年は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
}
そのタイプの日付に一致させたい場合は、次を使用します。
preg_match("~^\d{4}-\d{2}-\d{2}$~", $date)
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)
フォーマット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;
}
Laravel 5.7から、日付形式、つまり12/31/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);
}
それはすべて、この関数をどの程度厳密にしたいかによって異なります。たとえば、12を超える月と31を超える日を許可したくない場合(月に依存せず、date-logicを記述する必要があります)、かなり複雑になる可能性があります。
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})$/
[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');
}
このメソッドは、PHPで日付を検証するのに役立ちます。現在の方法は、mm/dd/yyyy形式用です。 checkdate のパラメーターシーケンスを explode の形式と区切り記号に従って更新する必要があります。
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;
}
}