有効な日付のPHPチェック、奇妙な日付変換
質問
日付/時刻が有効かどうかを確認する方法はありますか?これらは簡単に確認できると思います:
$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#1 SMP Wed Mar 5 11:36:49 EST 2008 i686 i686 i386 GNU /でPHP 5.2.5(cli)を実行(ビルド:2008年7月23日11:32:27) Linux
解決
<?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;
}
?>
他のヒント
ここで述べたように: 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'
echo date( 'Y-m-d'、strtotime($ date));
結果:&quot; 1999-11-30&quot;
strtotime
の結果は943920000です。これは、おおよそ Unixエポック(時間の測定基準)から1999-11-30まで。
文書化されている mysqlのバグ mktime()、localtime()、strtotime()
で、エポック前の時間(&quot; 0000-00-00 00:00:00&quot;を含む)を試みると、この奇数値がすべて返されます。リンクされたスレッドでは、これが実際にバグであるかどうかについていくつかの議論があります。
タイムスタンプは1970年から開始されているため、そうなるとは思わない とにかく動作します。
以下は、上記のようなdateTimesを比較などのためにタイムスタンプに変換するために使用する関数です。これは、「0000-00-00 00:00:00」を超える日付に対して、あなたにとって役に立つかもしれません。
/**
* 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);
}
範囲外の場合、一貫した結果を期待しないでください:
cf strtotime
cf Gnu Calendar-date-items .html
&quot;月の数値の場合、ISO 8601 format&#8216; year-month-day&#8217;許可されています、 ここで、年は任意の正数です。 月は01の間の数字です そして12 、そして日は 01〜31の数字。 A 先行ゼロが存在する必要があります 数は10未満です。&quot;
つまり、「0000-00-00」は奇妙な結果をもたらします、それは論理的です!
&quot;さらに、すべてではありません プラットフォームは負のタイムスタンプをサポートし、 したがって、日付範囲は Unixより前に限定されない エポック。これは、たとえば %e、%T、%R、および%D( その他)および 1月より前の日付 1、1970はWindowsでは動作しません。 Linuxディストリビューション、および他のいくつか オペレーティングシステム。&quot;
cf strftime
代わりに checkdate 関数を使用します(より堅牢):
月: 月は1〜12の間です。
日: 日は、指定された日数の許容日数内です 月。うるう年が取られます 考慮に入れます。
年: 年は1〜32767の間です。
このバージョンでは、フィールドを空にすることができ、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;
}
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));
}
<?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
上記のマーティンの回答を変更しました。これにより、あらゆるタイプの日付が検証され、希望の形式で返されます。
スクリプトの以下の行を編集して、フォーマットを変更するだけです strftime(&quot; 10-10-2012&quot ;, 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" ;
}
}
?>
次のコードを使用して、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);
}
<?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;
}
?>