14

日付/時刻が有効かどうかを確認する方法はありますか?これらは簡単に確認できると思います:

$date = '0000-00-00';
$time = '00:00:00';
$dateTime = $date . ' ' . $time;

if(strtotime($dateTime)) {
    // why is this valid?
}

本当に私を得るのはこれです:

echo date('Y-m-d', strtotime($date)); 

結果: "1999-11-30",

は?私は0000-00-00から1999-11-30に行きました???

日付がこれらの値のいずれかであるかどうかを比較して、私が持っている日付と等しいかどうかを確認できることはわかっていますが、確認するための非常に堅牢な方法ではありません。有効な日付があるかどうかを確認する良い方法はありますか? 誰でもこれをチェックするための良い機能を持っていますか?

編集: 人々は私が実行しているものを尋ねています: Linux localhost 2.6.18-53.1.14.el5 で PHP 5.2.5 (cli) (ビルド: 2008 年 7 月 23 日 11:32:27) を実行しています #1 SMP Wed Mar 5 11 :36:49 EST 2008 i686 i686 i386 GNU/Linux

4

10 に答える 10

23

php.netより

<?php
function isValidDateTime($dateTime)
{
    if (preg_match("/^(\d{4})-(\d{2})-(\d{2}) ([01][0-9]|2[0-3]):([0-5][0-9]):([0-5][0-9])$/", $dateTime, $matches)) {
        if (checkdate($matches[2], $matches[3], $matches[1])) {
            return true;
        }
    }

    return false;
}
?>
于 2008-09-26T19:15:01.217 に答える
5

ここで述べたように: https ://bugs.php.net/bug.php?id = 45647

ここにバグはありません。00-00-00は2000-00-00、つまり1999-12-00、つまり1999-11-30を意味します。バグはなく、完全に正常です。

そして、いくつかのテストで示されているように、少し不安な場合は、逆方向にロールバックすることが予想される動作です。

>> date('Y-m-d', strtotime('2012-03-00'))
string: '2012-02-29'
>> date('Y-m-d', strtotime('2012-02-00'))
string: '2012-01-31'
>> date('Y-m-d', strtotime('2012-01-00'))
string: '2011-12-31'
>> date('Y-m-d', strtotime('2012-00-00'))
string: '2011-11-30'
于 2012-03-29T21:07:19.120 に答える
2

echo date('Ymd', strtotime($date));

結果: "1999-11-30"

の結果strtotimeは 943920000 です。これは、おおよそ、Unix エポック(時間の測定基準) から 1999 年 11 月 30 日までの秒数です。

エポック前の時間 (「0000-00-00 00:00:00」を含む) を試行すると、この奇妙な値を返すすべてのmysql バグ文書化されています。mktime(), localtime(), strtotime()これが実際にバグであるかどうかについて、リンクされたスレッドでいくつかの議論があります。

タイムスタンプは 1970 年から開始されているため、とにかく動作するはずがないと思います。

以下は、「0000-00-00 00:00:00」を超える日付について、上記のようなdateTimesを比較などのタイムスタンプに変換するために使用する関数です。

/**
 * Converts strings of the format "YYYY-MM-DD HH:MM:SS" into php dates
 */
function convert_date_string($date_string)
{
    list($date, $time) = explode(" ", $date_string);
    list($hours, $minutes, $seconds) = explode(":", $time);
    list($year, $month, $day) = explode("-", $date);
    return mktime($hours, $minutes, $seconds, $month, $day, $year);
}
于 2008-09-26T19:11:25.627 に答える
1

mysql の日付フィールドの時間を使わずに日付変換を処理したいだけなら、私が行ったようにこの優れたコードを変更できます。この関数を実行しない私のバージョンの PHP では、毎回 "0000-00-00" が表示されます。迷惑。

function ConvertDateString ($DateString)
{
    list($year, $month, $day) = explode("-", $DateString);
    return date ("Y-m-d, mktime (0, 0, 0, $month, $day, $year));
}
于 2010-01-15T06:16:58.837 に答える
1

このバージョンでは、フィールドを空にすることができ、mm/dd/yy または mm/dd/yyyy 形式の日付を持ち、1 桁の時間を許可し、オプションの am/pm を追加し、時間の一致におけるいくつかの微妙な欠陥を修正します。

「23:14 AM」のような異常な時間も許容されます。

function isValidDateTime($dateTime) {
    if (trim($dateTime) == '') {
        return true;
    }
    if (preg_match('/^(\d{1,2})\/(\d{1,2})\/(\d{2,4})(\s+(([01]?[0-9])|(2[0-3]))(:[0-5][0-9]){0,2}(\s+(am|pm))?)?$/i', $dateTime, $matches)) {
        list($all,$mm,$dd,$year) = $matches;
        if ($year <= 99) {
            $year += 2000;
        }
        return checkdate($mm, $dd, $year);
    }
    return false;
}
于 2011-01-05T15:41:28.257 に答える
1

範囲外の場合、首尾一貫した結果を期待しないでください。

cf strtotime

cf Gnu Calendar-date-items .html

「数値の月については、ISO 8601 フォーマット '年-月-日' を使用できます。ここで、年は任意の正 の数値、月は 01 から 12までの数値、日は 01 から 31 までの数値です。先頭のゼロは数が 10 未満の場合に表示されます。」

したがって、「0000-00-00」は奇妙な結果をもたらしますが、これは論理的です!


「さらに、すべてのプラットフォームが負のタイムスタンプをサポートしているわけではないため、日付範囲は Unix エポックよりも前に制限される場合があります。これは、たとえば %e、%T、%R、%D (他にもある可能性があります) およびそれより前の日付を意味します。 1970 年 1 月 1 日は、Windows、一部の Linux ディストリビューション、およびその他のいくつかのオペレーティング システムでは動作しません。"

cf strftime


代わりにcheckdate関数を使用します (より堅牢):

month:月は 1 から 12 までの範囲です。

day: 日は、指定された月の許容日数内です。うるう年が考慮されます。

年:年は 1 から 32767 までの範囲です。

于 2008-09-29T12:07:04.607 に答える
0

次のコードを使用して、ExtJSアプリケーションからの日付を検証しました。

function check_sql_date_format($date) {
    $date = substr($date, 0, 10);
    list($year, $month, $day) = explode('-', $date);
    if (!is_numeric($year) || !is_numeric($month) || !is_numeric($day)) {
        return false;
    }
    return checkdate($month, $day, $year);
}
于 2012-04-25T10:03:22.563 に答える
0

上記のマーティンの回答を変更したところです。これにより、あらゆるタイプの日付が検証され、希望の形式で返されます。

スクリプトstrftime( "10-10-2012"、strtotime($ dt));の行の下を編集してフォーマットを変更するだけです。

<?php
echo is_date("13/04/10");

function is_date( $str ) {
    $flag = strpos($str, '/');

    if(intval($flag)<=0){
        $stamp = strtotime( $str );
    } else {
        list($d, $m, $y) = explode('/', $str);    
        $stamp = strtotime("$d-$m-$y");
    } 
    //var_dump($stamp) ;

    if (!is_numeric($stamp)) {
        //echo "ho" ;
        return "not a date" ;        
    }

    $month = date( 'n', $stamp ); // use n to get date in correct format
    $day   = date( 'd', $stamp );
    $year  = date( 'Y', $stamp );

    if (checkdate($month, $day, $year)) {
        $dt = "$year-$month-$day" ;
        return strftime("%d-%b-%Y", strtotime($dt));
        //return TRUE;
    } else {
        return "not a date" ;
    }
}
?>
于 2012-01-20T08:29:44.750 に答える
0
<?php
function is_valid_date($user_date=false, $valid_date = "1900-01-01") {
    $user_date = date("Y-m-d H:i:s",strtotime($user_date));
    return strtotime($user_date) >= strtotime($valid_date) ? true : false;
}

echo is_valid_date("00-00-00") ? 1 : 0;    // return 0

echo is_valid_date("3/5/2011") ? 1 : 0;    // return 1
于 2012-03-16T18:08:34.630 に答える
-1
<?php

function is_date( $str ) {
    $stamp = strtotime( $str );

    if (!is_numeric($stamp)) {
        return FALSE;
    }
    $month = date( 'm', $stamp );
    $day   = date( 'd', $stamp );
    $year  = date( 'Y', $stamp );

    if (checkdate($month, $day, $year)) {
        return TRUE;
    }
    return FALSE;
}
?>
于 2011-09-19T18:27:36.493 に答える