2016-01-20 111 views
1

我爲其中發送到DateTime::modify($string)$string變量是從用戶編輯數據庫中讀取的情況下,我怎麼能驗證$stringDateTime::modify()正確的字符串?的日期時間驗證字符串輸入::修改()

+0

可能這個鏈接會幫助你。 http://stackoverflow.com/questions/16075159/check-if-a-string-is-a-valid-date-using-datetime-tryparse –

+0

@RaviHirani你的鏈接問一個類似的C#問題,但我不是確定實現建議可以用PHP完成? –

回答

0

你可以做這樣的事情,並調用它,你將字符串傳遞到您的實際日期之前:

function modifyIsValid($modifyString) { 
    $d = new DateTime(); 
    $isValid = $d->modify($modifyString); 

    if ($isValid === false) { 
     return false; 
    } 

    return true; 
} 

->modify()返回false是傳遞的字符串是無效的,雖然它也將引發增加一個E_Warning這是不理想的。

$d = new DateTime(); 
$string = 'not a valid modifier'; 

if (modifyIsValid($string)) { 
    // Continue 
} else { 
    // Print a friendly error message. 
} 

您可以在手冊中找到有關它的更多信息:http://php.net/manual/en/datetime.modify.php

希望它能幫助。

+0

這看起來像是驗證字符串的好方法,但我需要處理警告,這是否可以簡單地禁止警告? –

+0

@ChristopherKarlsson這可能是擺脫錯誤的一種可能的方式,畢竟即使你壓制了錯誤,你仍然在處理它,所以它應該沒問題。執行檢查的另一種方式最有可能使用正則表達式來驗證字符串對所有在這裏找到的有效格式:http://php.net/manual/en/datetime.formats.php – Mikey

+0

我會接受這個答案,因爲它似乎是最接近你可以做一個乾淨的驗證,即使它提出了一個警告,我會按照@pherris答案中的建議處理警告。 –

1

試試這個功能基於格式

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

功能,從這個answerphp.net

+0

我正在使用此功能在應用修改功能之前檢查日期的格式。我需要驗證修改正確格式日期的字符串,該字符串應該被驗證爲DateTime :: modify()可以理解的字符串。 –

+0

從你的函數內部調用這個函數 –

+0

爲什麼你必須添加'$ d->格式($ format)== $ date'? – systemovich

0

複製驗證時間戳字符串這之前它來檢查用戶輸入通常的最佳實踐保存到數據庫中,以便您可以在出路時對其有信心。

你可以使用try/catch塊,以及:

try { 
    $date = new DateTime('2016-12-12'); 
    $date->modify('+1 dayBLA'); 
    echo $date->format('Y-m-d'); 
} catch (Exception $e) { 
    echo 'Caught exception: ', $e->getMessage(), "\n"; 
} 

編輯:看這個,如果傳遞給modify的字符串無效後(不是日期字符串,我原本應該),你的代碼會拋出一個Warning也不例外。

可能能夠觸發Warning暫時作爲例外與set_error_handler對待。

function warning_handler($errno, $errstr, $errfile, $errline, array $errcontext) { 
    throwErrorException($errstr, 0, $errno, $errfile, $errline); 
} 
set_error_handler('warning_handler', E_WARNING); 

try { 
    $date = new DateTime('2016-12-12'); 
    $date->modify('+1 daybla'); 
    echo $date->format('Y-m-d'); 
} catch (Exception $e) { 
    echo 'Caught exception: ', $e->getMessage(), "\n"; 
} 

restore_error_handler(); 

但是,這開始看起來有點討厭。在調用modify方法之前和之後,可能會比較清晰(在您的代碼中,而不是您的日誌中),以查看它們是否不同。

$date = new DateTime('2016-12-12'); 
$origDate = clone $date; //I believe this will get you an independent object 
$date->modify('+1 daybla'); 
if ($origDate == $date) { 
    echo "Bad value passed to modify, probably a warning in the logs :("; 
} 
+0

我同意輸入前應該檢查輸入到數據庫中,我這樣做,但我也想在這方面驗證,如果可能的話- 以防萬一。我試着按照你的建議添加一個try和catch,但是當修改失敗時,這仍然會引發警告。 –

+0

我只是注意到了 - 環顧四周後,我看不到一個很好的方法來做到這一點。很明顯,你傳遞給'modify'的字符串的正則表達式是最好的,但是這個方法所使用的字符串似乎是非常不同的。也許你可以通過限制用戶輸入來解決問題,例如三個輸入:1)'+'/'-',2)'小時'/'天'3)計數(一個int)。我用幾個其他選項編輯了答案,你可以試試 - 祝你好運! – pherris

0

有點晚在這裏聚會,這完全適用於我......

function isDateModifyValid($String) 
{ 
    if (strlen($String) == 0) { return false; } 
    $now = new \DateTime(null, new \DateTimeZone("UTC")); 
    $rtn = false; // Default return value 
    @$now->modify($String) && $rtn = true; 
    // If modify($string) fails, $rtn won't set to true, else $rtn will set to true 
    //^^ @ suppress error 
    return $rtn; 
} 

//TEST DATA 
foreach (array("+1 hour", "+2 hour, -5 minutes", "12:00", "dsfv", "13:00, + 1 hour", "Yesterday, 12:00", "Neext weeekc", "Next month") as $testString) 
{ 
    if (isDateModifyValid($testString)) 
    { 
     echo "VALID ::: $testString\n"; 
    } else { 
     echo "INVALID ::: $testString\n"; 
    } 
} 

VALID ::: +1 hour VALID ::: +2 hour, -5 minutes VALID ::: 12:00 INVALID ::: dsfv VALID ::: 13:00, + 1 hour VALID ::: Yesterday, 12:00 INVALID ::: Neext weeekc VALID ::: Next month

+0

你的回答補充說,其他人不知道? – GrumpyCrouton