web-dev-qa-db-ja.com

PHPで変数が有効な日付であるかどうかを確認します

CSVファイルからデータをインポートするスクリプトを作成しています。これを実行しているときに、変数をチェックして、有効な日付文字列かどうかを確認できるようにしたいと思います。

スティングが日付であるかどうかを確認するいくつかの方法を見てきましたが、それらのほとんどは、現在、フォーマットを要求しています。日付の形式はわかりません。

今私はstrtotime()を使用していますが、これは簡単に失敗します

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

この場合、「5月」は個人の名であり、日付ではありません。

より信頼性の高い機能を推奨できる人はいますか?

あなたからの質問に基づいて編集します。

私の場合、変数が「日付」として渡されるには、日/月/年に固有である必要があるため、「5月」だけが曖昧になります。

それと以下のポールの良い点に基づいて、文字列に次のような数字が含まれているかどうかをテストすることもできます。

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

これは当面のニーズをカバーしているようですが、何か問題を見つけたり、改善を提案したりできますか?

39
Alex

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";
56
saluce

この問題に対するオールインワンの答えはないと思います。ユースケースに応じて、異なる戦略を使用できます。

あなたのstrtotime()は完璧なソリューションですが、あなたが言うように、あなたは誤検知に終わるかもしれません。どうして? mayはWordまたは名前の場合があるためです。しかし、strtotime('May')の結果は何ですか?

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

そのため、月のみを指定すると、現在の年の日付と、指定した月の午前0時に始まる現在の日付が返されます。考えられる解決策は、文字列に現在の日付および/または現在の年が含まれているかどうかをチェックすることです。この方法で、日付が完全修飾日付で有効であることを確認できます。

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

ほとんどのケースをカバーするようにしてください。最新の日付形式をチェックする正規表現を見つけることができると確信しています。

いずれにせよ、防弾にする簡単な方法がないため、機能を適宜調整する必要がある場合があります。

5
Boris Guéry

私はこれがずっと前に尋ねられたことを知っていますが、これを探して正規表現を避けようとすると、私はこれを思いつきました:

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

これは、文字列に strtotime が含まれていることを確認し、strpbrkが日付を出力することを確認することで、上記の投稿された月のみがstrtotimeに渡される問題を取り除くために機能します。

そして、私は知らなかった機能が存在することを学びました。

これが誰かを助けることを願っています。

0
Bryan