PHP類Crond時間規則演算法
阿新 • • 發佈:2018-12-25
<?php /** * Created by PhpStorm. * User: duyue * Date: 2018/2/20 * Time: 23:10 * 此類僅用於判斷給定的時間是否符合時間規則,如果符合則返回true其它業務邏輯自行處理 * 使用說明 * format = '* * * * * '; * 本類模仿crond的規則分5個部分分別是分、時、日期、月、周(的第幾天) * 每部分可單獨設定為一個數,如:1 * * * * ,當分為1時 true * 可以使用 '/' 來分開設定重複規則,如: * / 1 * * * * , 每分鐘 ; * / 2 * * * * 每兩分鐘(注意每部分之間是沒有空格的,這裡是PHP的註釋部分) * 可以設定區間: 4-20/2 * * * * , 當分為4 - 20之間,並且為2的倍數時 * 可以為集合: * /5,8,10 * * * * , 當分為5,8,10時返回true,其它部分同理。 * '0 23 * * 6' 每週六的11點 * '* 23-7/1 * * * ' 每天晚上23-7點,每隔一小時 */ namespace app\extend; class CrondTime{ public static function check($format,$check_time = 0) { $time = intval($check_time) > 0 ? $check_time : time(); $cNumber = [ date('i',$time), //分 0 - 59 date('H',$time), //時 0 - 23 date('j',$time), //日期, 1- 31 date('m',$time), //月 1 - 12 date('w',$time), //周 星期中的第幾天 0(週日)至6(週六) ]; $cronArr = explode(' ',$format); //逐個檢查,非*全符合則返回true,否則返回false for($i = 0; $i<5;$i++){ if($cronArr[$i] == '*' || empty($cronArr[$i])) continue; if(self::checkNumber($cNumber[$i],$cronArr[$i]) === false){ return false; } } return true; } /** * 檢查一個數字是否符合 * @param $number 要檢查的數字 * @param $str 規則字元 * @return bool 符合返回true */ private function checkNumber($number,$str) { if(strpos($str,'/') === false && strpos($str,',') === false && strpos($str,'-') === false){ //單數 if($number == $str) return true; return false; } //檢查是否含有'/' if(strpos($str,'/') === false){ //不含'/' if(strpos($str,',') !== false){ //集合 if(in_array($number,explode(',',$str))) return true; return false; } if(strpos($str,'-') !== false){ //區間 $areaArr = explode('-',$str); $min = intval(trim($areaArr[0])); $max = intval(trim($areaArr[1])); if($number >= $min && $number <= $max) return true; return false; } }else{ //有 '/' ,分左右兩部分,左邊檢查集合、區間。右側檢查餘數是否為0 $leftCheck = $rightCheck = false; $tmp = explode('/',$str); $leftStr = $tmp[0]; $rightStr = $tmp[1]; //如果左側是*的話,右側為數字則取模 $leftCheck = self::checkLevel3($number,$leftStr,true); $rightCheck = self::checkLevel3($number,$rightStr,false); if($leftCheck===true && $rightCheck === true) return true; return false; } } /** * 檢查3級字元 * @param $number * @param $str * @param bool $is_left * @return bool */ private function checkLevel3($number,$str,$is_left = false){ if($str === '*') return true; //三級中已經沒有 '/' ,只需要檢查是否是單數、集合、區間。 if(strpos($str,',') === false && strpos($str,'-') === false){ if($is_left === true){ if($number == $str) return true; return false; }else{ //echo $number;exit(); //右側單數,進行取模運算 if($number%$str == 0) return true; return false; } } if(strpos($str,',') !== false){ //集合 if(in_array($number,explode(',',$str))) return true; return false; } if(strpos($str,'-') !== false){ //區間 $areaArr = explode('-',$str); $min = intval(trim($areaArr[0])); $max = intval(trim($areaArr[1])); if($number >= $min && $number <= $max) return true; return false; } } }
這裡使用的名稱空間,複製的時候稍注意一點。
防linux crond 時間規則演算法,初步測試暫未發現什麼問題。如果你發現的BUG歡迎留言。