- isMatch_YYYYMMDD
- 日付が西暦4桁、月2桁、日2桁の形式かつ有効な日付かどうか
- isMatch_HHMMSS
- 時刻が時2桁、分2桁、秒2桁の形式かつ有効な時刻かどうか
- isMatchDateTime
- 上2つを確認する。日付と時刻は半角空白区切り
- preg_matchを使用してチェックしている
- $_exclusive_date_list変数で指定した形式の日付は有効な日付とする
/**
* 日付チェックを除外する日付のリスト
* @var array
*/
$_exclusive_date_list = array('00000000');
/**
* 日付が西暦4桁、月2桁、日2桁の形式かどうか確認する
* @param string $text 確認する文字列
* @param string $delim 日付区切り文字。/を区切り文字とするときは'\/'とエスケープ文字を入れる
* @param boolean $errorIfEmpty 空文字列をエラーとするか TRUE:する FALSE:しない
* @return boolean 有効な日付フォーマットかどうか TRUE:有効 FALSE:有効でない
*/
function isMatch_YYYYMMDD($text, $delim = '-', $errorIfEmpty = TRUE) {
global $_exclusive_date_list;
#空文字チェック
if($text == ''){
return !$errorIfEmpty;
}
#年 0000-9999 月 00-99 日 00-99
$pattern = '/^([0-9]{4})' . $delim . '([0-9]{2})' . $delim . '([0-9]{2})$/';
$matches = array();
$match = isMatch($pattern, $text, $errorIfEmpty, $matches);
if(!$match) {
return FALSE;
}
#日付チェックを除外するかチェック
if(in_array($matches[1] . $matches[2] . $matches[3], $_exclusive_date_list)) {
return TRUE;
}
# 日付存在するかチェック
if(!checkdate((int)$matches[2], (int)$matches[3], (int)$matches[1])) {
return FALSE;
}
return TRUE;
}
/**
* 時刻が時2桁、分2桁、秒2桁の形式かどうか確認する
* @param string $text 確認する文字列
* @param string $decimal 秒未満の桁数
* @param string $delim 時刻区切り文字
* @param boolean $errorIfEmpty 空文字列をエラーとするか TRUE:する FALSE:しない
* @return boolean 有効な時刻フォーマットかどうか TRUE:有効 FALSE:有効でない
*/
function isMatch_HHMMSS($text, $decimal = 0, $delim = ':', $errorIfEmpty = TRUE) {
#空文字チェック
if($text == ''){
return !$errorIfEmpty;
}
//うるう秒はMySQLでは登録できないためフォーマットエラーとする。
//対応する場合は下の正規表現を使用する
//#時 00-23 分 00-59 秒 00-60
//$pattern = '/^(0[0-9]{1}|1{1}[0-9]{1}|2{1}[0-3]{1})' . $delim . '(0[0-9]{1}|[1-5]{1}[0-9]{1})' . $delim . '(0[0-9]{1}|[1-5]{1}[0-9]{1}|60)';
#時 00-23 分 00-59 秒 00-59
$pattern = '/^(0[0-9]{1}|1{1}[0-9]{1}|2{1}[0-3]{1})' . $delim . '(0[0-9]{1}|[1-5]{1}[0-9]{1})' . $delim . '(0[0-9]{1}|[1-5]{1}[0-9]{1})';
# 小数部があればパターンに追加
if($decimal > 0) {
$pattern = $pattern . sprintf('\.([0-9]{%d})', $decimal);
}
$pattern = $pattern . '$/';
return isMatch($pattern, $text, $errorIfEmpty);
}
/**
* 日時フォーマットかどうか確認する
* 日付と時刻の間は半角空白で区切られていること
* @param string $text 確認する文字列
* @param string $decimal 秒未満の桁数
* @param boolean $errorIfEmpty 空文字列をエラーとするか TRUE:する FALSE:しない
* @param string $date_delim 日付区切り文字。/を区切り文字とするときは'\/'とエスケープ文字を入れる
* @param string $time_delim 時刻区切り文字
* @return boolean 有効な日時フォーマットかどうか TRUE:有効 FALSE:有効でない
*/
function isMatchDateTime($text, $decimal = 0, $errorIfEmpty = TRUE, $date_delim = '-', $time_delim = ':') {
#空文字チェック
if($text == ''){
return !$errorIfEmpty;
}
# 日付と時刻に分解
$datetime = explode(' ', $text);
if(count($datetime) < 2) {
return FALSE;
}
# 日付
if(!isMatch_YYYYMMDD($datetime[0], $date_delim)) {
return FALSE;
}
# 時刻
if(!isMatch_HHMMSS($datetime[1], $decimal, $time_delim)) {
return FALSE;
}
return TRUE;
}
/**
* 正規表現パターン検索
* @param string $pattern 正規表現
* @param string $text 確認する文字列
* @param boolean $errorIfEmpty 空文字列をエラーとするするか TRUE:する FALSE:しない
* @return boolean 正規表現に合致するか TRUE:合致する FALSE:合致しない
*/
function isMatch($pattern, $text, $errorIfEmpty = TRUE, &$matches = array()) {
#空文字チェック
if($text == ''){
return !$errorIfEmpty;
}
if(!preg_match($pattern, $text, $matches)) {
return FALSE;
} else {
return TRUE;
}
}
テストコード(全分岐網羅していない)
function testisMatch_YYYYMMDD($date, $exists = TRUE, $delim = '\/'){
if(isMatch_YYYYMMDD($date, $delim, $exists))
{echo '<font color="blue">'.$date.' 正しい日付</font><br/>';}
else
{echo '<font color="red">'.$date.' 不正な日付</font><br/>';}
}
function testisMatch_HHMMSS($time, $decimal = 0, $delim = ':'){
if(isMatch_HHMMSS($time, $decimal, $delim))
{echo '<font color="blue">'.$time.' 正しい時刻</font><br/>';}
else
{echo '<font color="red">'.$time.' 不正な時刻</font><br/>';}
}
echo '<h4>年が不正</h4>';
testisMatch_YYYYMMDD('/01/01'); #値なし
testisMatch_YYYYMMDD('200/01/01'); #桁不足
echo '<h4>月が不正</h4>';
testisMatch_YYYYMMDD('2012//01'); #値なし
testisMatch_YYYYMMDD('2012/1/01'); #桁不足
testisMatch_YYYYMMDD('2012/00/01'); #無効な月
testisMatch_YYYYMMDD('2012/13/01'); #無効な月
echo '<h4>日が不正</h4>';
testisMatch_YYYYMMDD('2012/01/'); #値なし
testisMatch_YYYYMMDD('2012/01/1'); #桁不足
testisMatch_YYYYMMDD('2012/01/00'); #無効な日
testisMatch_YYYYMMDD('2012/01/32'); #無効な日
testisMatch_YYYYMMDD('2014/02/29'); #無効な日
echo '<h4>0000/00/00はOK</h4>';
testisMatch_YYYYMMDD('0000/00/00');
echo '<h4>1000日チェック</h4>';
for($i = 0; $i <= 1000; $i++){
$date = date('Y/m/d',mktime(0,0,0,date('n'),date('j')+$i,date('Y')-1));
testisMatch_YYYYMMDD($date);
}
echo '<h4>年が不正(区切りなし)</h4>';
testisMatch_YYYYMMDD('0101', TRUE, ''); #値なし
testisMatch_YYYYMMDD('1000101', TRUE, ''); #桁不足
echo '<h4>全部ゼロはOK</h4>';
testisMatch_YYYYMMDD('00000000', TRUE, '');
echo '<h4>うるう年はOK</h4>';
testisMatch_YYYYMMDD('20120229', TRUE, ''); #2/29
echo '<h4>1000日チェック(区切りなし)</h4>';
for($i = 0; $i <= 1000; $i++){
$date = date('Ymd',mktime(0,0,0,date('n'),date('j')+$i,date('Y')-1));
testisMatch_YYYYMMDD($date, TRUE, '');
}
echo '<h4>時が不正</h4>';
testisMatch_HHMMSS(':59:59'); #値なし
testisMatch_HHMMSS('0:59:59'); #桁不足
testisMatch_HHMMSS('24:59:59'); #無効な時
echo '<h4>秒が不正</h4>';
testisMatch_HHMMSS('00:00:'); #値なし
testisMatch_HHMMSS('00:00:0'); #桁不足
testisMatch_HHMMSS('00:00:60'); #うるう秒はNG
echo '<h4>ミリ秒が不正</h4>';
testisMatch_HHMMSS('00:00:00.'); #値なし
testisMatch_HHMMSS('00:00:00.01'); #桁不足
echo '<h4>30時間チェック</h4>';
for($i = 0; $i <= 30; $i++){
$time = date('H:i:s',mktime(0+$i,0,0,date('n'),date('j'),date('Y')));
testisMatch_HHMMSS($time);
}
echo '<h4>100分チェック</h4>';
for($i = 0; $i <= 100; $i++){
$time = date('H:i:s',mktime(0,0+$i,0,date('n'),date('j'),date('Y')));
testisMatch_HHMMSS($time);
}
echo '<h4>100秒チェック</h4>';
for($i = 0; $i <= 100; $i++){
$time = date('H:i:s',mktime(0,0,0+$i,date('n'),date('j'),date('Y')));
testisMatch_HHMMSS($time);
}
echo '<h4>100ミリ秒チェック</h4>';
$millitime = date('H:i:s',mktime(0,0,0,date('n'),date('j'),date('Y')));
for($i = 0; $i <= 100; $i++){
$time = date('H:i:s',mktime(0,0,0+$i,date('n'),date('j'),date('Y')));
testisMatch_HHMMSS($millitime . '.' . sprintf('%03d', $i),3);
}