<?php
/**
* taskPHP
* @author 码农<8044023@qq.com>,cqcqphper 小草<cqcqphper@163.com>
* @copyright taskPHP
* @license https://gitee.com/cqcqphper/taskPHP
*/
namespace taskphp;
/**
* 定时命令类
* @author cqcqphper 小草<cqcqphper@163.com>
*
*/
class Crontab implements \Serializable{
const LOOP=TRUE;
protected $_hours;
protected $_minutes;
protected $_seconds;
protected $_day;
protected $_month;
protected $_year;
protected $_week;
protected $_many_key='';
/**
* 循环标记
* @var string
*/
private static $_P='/';
/**
* 任务时间,不做任何设置,按每分钟执行一次
*/
public function __construct(){
$this->_hours=self::LOOP;
$this->_minutes=self::LOOP;
$this->_seconds=0;
$this->_day=self::LOOP;
$this->_month=self::LOOP;
$this->_year=self::LOOP;
$this->_week=self::LOOP;
}
/**
* 创建定时循环
* 设置循环值,比循环值小的单位必须为固定值
* 比循环值大的单位作废,如:设置日循环,月跟年的设置作废
* @param int $var
* @return string
*/
public static function create_loop($var){
return self::$_P.intval($var);
}
/**
* 解析一个定时循环,返回具体值
* @param string $var
* @return boolean|number
*/
public static function parse_loop($var){
if (!self::is_loop($var)) return false;
return intval(substr($var, 1));
}
/**
* 指定值是否是定时循环值
* @param string $var
* @return boolean
*/
public static function is_loop($var){
if ($var===self::LOOP) return false;
if (is_array($var)) return false;
return self::$_P==substr($var,0,1);
}
/**
* 指定值是否是单一固定值
* @param mixed $var
* @return boolean
*/
public static function is_fix($var){
if ($var===self::LOOP) return false;
return !is_array($var);
}
/**
* 获取val列表内的当前值 用于单值多选设置
* @param int|array $val
* @param int $nval
* @return unknown
*/
protected function _get_now_val($key,$val,$nval){
if(is_array($val)){
sort($val,SORT_NUMERIC);
foreach ($val as $v){
if($v==$nval) return $nval;
}
$this->_many_key=$key;
return $val[0];
}
return $nval;
}
/**
* 计算下一次执行的时间
* @return int
*/
public static function get_next_run_time($now_time=null,$crontab=null){
if ($now_time==null)$now_time=time();
$h=$crontab->get_hours();
$i=$crontab->get_minutes();
$s=$crontab->get_seconds();
$d=$crontab->get_day();
$m=$crontab->get_month();
$y=$crontab->get_year();
$w=$crontab->get_week();
$nh=date("G",$now_time);
$ni=intval(date("i",$now_time));
$ns=intval(date("s",$now_time));
$ny=date("Y",$now_time);
$nm=date("n",$now_time);
$nd=date("j",$now_time);
$nw=date("w",$now_time);
//定量循环
if(self::is_loop($y)){
$loop_val=self::parse_loop($y);
$_m=self::is_fix($m)?$m:'01';
$_d=self::is_fix($d)?$d:'01';
$_h=self::is_fix($h)?$h:'00';
$_i=self::is_fix($i)?$i:'00';
$_s=self::is_fix($s)?$s:'00';
/** 单值多选设置 开始 **/
$_m=$crontab->_get_now_val('months',$m,$nm);
$_d=$crontab->_get_now_val('day',$d,$nd);
$_h=$crontab->_get_now_val('hours',$h,$nh);
$_i=$crontab->_get_now_val('minute',$i,$ni);
$_now_time=strtotime("{$ny}-{$_m}-{$_d} {$_h}:{$_i}:{$_s}");
if($_now_time<$now_time){
if($crontab->_many_key=='months'){
$_now_time=strtotime("+ 1 year",$_now_time);
}elseif($crontab->_many_key=='day'){
$_now_time=strtotime("+ 1 months",$_now_time);
}elseif($crontab->_many_key=='hours'){
$_now_time=strtotime("+ 1 day",$_now_time);
}elseif($crontab->_many_key=='minute'){
$_now_time=strtotime("+ 1 hours",$_now_time);
}
}
/** 单值多选设置 结束 **/
//单值多选设置 $now_time改为$_now_time
return strtotime(date("Y",strtotime("+ {$loop_val} year",$_now_time))."-{$_m}-{$_d} {$_h}:{$_i}:{$_s}");
}
if(self::is_loop($m)){
$loop_val=self::parse_loop($m);
$_d=self::is_fix($d)?$d:'01';
$_h=self::is_fix($h)?$h:'00';
$_i=self::is_fix($i)?$i:'00';
$_s=self::is_fix($s)?$s:'00';
/** 单值多选设置 开始 **/
$_m=$crontab->_get_now_val('months',$m,$nm);
$_d=$crontab->_get_now_val('day',$d,$nd);
$_h=$crontab->_get_now_val('hours',$h,$nh);
$_i=$crontab->_get_now_val('minute',$i,$ni);
$_now_time=strtotime("{$ny}-{$_m}-{$_d} {$_h}:{$_i}:{$_s}");
if($_now_time<$now_time){
if($crontab->_many_key=='months'){
$_now_time=strtotime("+ 1 year",$_now_time);
}elseif($crontab->_many_key=='day'){
$_now_time=strtotime("+ 1 months",$_now_time);
}elseif($crontab->_many_key=='hours'){
$_now_time=strtotime("+ 1 day",$_now_time);
}elseif($crontab->_many_key=='minute'){
$_now_time=strtotime("+ 1 hours",$_now_time);
}
}
/** 单值多选设置 结束 **/
//单值多选设置 $now_time改为$_now_time
return strtotime(date("Y-m",strtotime("+ {$loop_val} months",$_now_time))."-{$_d} {$_h}:{$_i}:{$_s}");
}
if(Crontab::is_loop($d)){
$loop_val=self::parse_loop($d);
$_h=self::is_fix($h)?$h:'00';
$_i=self::is_fix($i)?$i:'00';
$_s=self::is_fix($s)?$s:'00';
/** 单值多选设置 开始 **/
$_m=$crontab->_get_now_val('months',$m,$nm);
$_d=$crontab->_get_now_val('day',$d,$nd);
$_h=$crontab->_get_now_val('hours',$h,$nh);
$_i=$crontab->_get_now_val('minute',$i,$ni);
$_now_time=strtotime("{$ny}-{$_m}-{$_d} {$_h}:{$_i}:{$_s}");
if($_now_time<$now_time){
if($crontab->_many_key=='months'){
$_now_time=strtotime("+ 1 year",$_now_time);
}elseif($crontab->_many_key=='day'){
$_now_time=strtotime("+ 1 months",$_now_time);
}elseif($crontab->_many_key=='hours'){
$_now_time=strtotime("+ 1 day",$_now_time);
}elseif($crontab->_many_key=='minute'){
$_now_time=strtotime("+ 1 hours",$_now_time);
}
}
/** 单值多选设置 结束 **/
//单值多选设置 $now_time改为$_now_time
return strtotime(date("Y-m-d",strtotime("+ {$loop_val} day",$_now_time))." {$_h}:{$_i}:{$_s}");
}
if(self::is_loop($h)){
$loop_val=self::parse_loop($h);
$_i=self::is_fix($i)?$i:'00';
$_s=self::is_fix($s)?$s:'00';
/** 单值多选设置 开始 **/
$_m=$crontab->_get_now_val('months',$m,$nm);
$_d=$crontab->_get_now_val('day',$d,$nd);
$_h=$crontab->_get_now_val('hours',$h,$nh);
$_i=$crontab->_get_now_val('minute',$i,$ni);
$_now_time=strtotime("{$ny}-{$_m}-{$_d} {$_h}:{$_i}:{$_s}");
if($_now_time<$now_time){
if($crontab->_many_key=='months'){
$_now_time=strtotime("+ 1 year",$_now_time);
}elseif($crontab->_many_key=='day'){
$_now_time=strtotime("+ 1 months",$_now_time);
}elseif($crontab->_many_key=='hours'){
$_now_time=strtotime("+ 1 day",$_now_time);
}elseif($crontab->_many_key=='minute'){
$_now_time=strtotime("+ 1 hours",$_now_time);
}
}
/** 单值多选设置 结束 **/
//单值多选设置 $now_time改为$_now_time
return strtotime(date("Y-m-d H",strtotime("+ {$loop_val} hours",$_now_time)).":{$_i}:{$_s}");
}
if(Crontab::is_loop($i)){
$loop_val