zoukankan      html  css  js  c++  java
  • ParseCrontab类,解析时间规则

    <?php
    
    /**
     * Created by PhpStorm.
     * User: ClownFish 187231450@qq.com
     * Date: 14-12-27
     * Time: 上午11:59
     */
    class ParseCrontab
    {
        static public $error;
    
        /**
         *  解析crontab的定时格式,linux只支持到分钟/,这个类支持到秒
         * @param string $crontab_string :
         *
         *      0     1    2    3    4    5
         *      *     *    *    *    *    *
         *      -     -    -    -    -    -
         *      |     |    |    |    |    |
         *      |     |    |    |    |    +----- day of week (0 - 6) (Sunday=0)
         *      |     |    |    |    +----- month (1 - 12)
         *      |     |    |    +------- day of month (1 - 31)
         *      |     |    +--------- hour (0 - 23)
         *      |     +----------- min (0 - 59)
         *      +------------- sec (0-59)
         * @param int $start_time timestamp [default=current timestamp]
         * @return int unix timestamp - 下一分钟内执行是否需要执行任务,如果需要,则把需要在那几秒执行返回
         * @throws InvalidArgumentException 错误信息
         */
        static public function parse($crontab_string, $start_time = null)
        {
            if (is_array($crontab_string)) {
                return self::_parse_array($crontab_string, $start_time);
            }
            if (!preg_match('/^((*(/[0-9]+)?)|[0-9-\,/]+)s+((*(/[0-9]+)?)|[0-9-\,/]+)s+((*(/[0-9]+)?)|[0-9-\,/]+)s+((*(/[0-9]+)?)|[0-9-\,/]+)s+((*(/[0-9]+)?)|[0-9-\,/]+)s+((*(/[0-9]+)?)|[0-9-\,/]+)$/i', trim($crontab_string))) {
                if (!preg_match('/^((*(/[0-9]+)?)|[0-9-\,/]+)s+((*(/[0-9]+)?)|[0-9-\,/]+)s+((*(/[0-9]+)?)|[0-9-\,/]+)s+((*(/[0-9]+)?)|[0-9-\,/]+)s+((*(/[0-9]+)?)|[0-9-\,/]+)$/i', trim($crontab_string))) {
                    self::$error = "Invalid cron string: " . $crontab_string;
                    return false;
                }
            }
            if ($start_time && !is_numeric($start_time)) {
                self::$error = "$start_time must be a valid unix timestamp ($start_time given)";
                return false;
            }
            $cron = preg_split("/[s]+/i", trim($crontab_string));
            $start = empty($start_time) ? time() : $start_time;
    
            if (count($cron) == 6) {
                $date = array(
                    'second' => self::_parse_cron_number($cron[0], 0, 59),
                    'minutes' => self::_parse_cron_number($cron[1], 0, 59),
                    'hours' => self::_parse_cron_number($cron[2], 0, 23),
                    'day' => self::_parse_cron_number($cron[3], 1, 31),
                    'month' => self::_parse_cron_number($cron[4], 1, 12),
                    'week' => self::_parse_cron_number($cron[5], 0, 6),
                );
            } elseif (count($cron) == 5) {
                $date = array(
                    'second' => array(1 => 1),
                    'minutes' => self::_parse_cron_number($cron[0], 0, 59),
                    'hours' => self::_parse_cron_number($cron[1], 0, 23),
                    'day' => self::_parse_cron_number($cron[2], 1, 31),
                    'month' => self::_parse_cron_number($cron[3], 1, 12),
                    'week' => self::_parse_cron_number($cron[4], 0, 6),
                );
            }
            if (
                in_array(intval(date('i', $start)), $date['minutes']) &&
                in_array(intval(date('G', $start)), $date['hours']) &&
                in_array(intval(date('j', $start)), $date['day']) &&
                in_array(intval(date('w', $start)), $date['week']) &&
                in_array(intval(date('n', $start)), $date['month'])
    
            ) {
                return $date['second'];
            }
            return null;
        }
    
        /**
         * 解析单个配置的含义
         * @param $s
         * @param $min
         * @param $max
         * @return array
         */
        static protected function _parse_cron_number($s, $min, $max)
        {
            $result = array();
            $v1 = explode(",", $s);
            foreach ($v1 as $v2) {
                $v3 = explode("/", $v2);
                $step = empty($v3[1]) ? 1 : $v3[1];
                $v4 = explode("-", $v3[0]);
                $_min = count($v4) == 2 ? $v4[0] : ($v3[0] == "*" ? $min : $v3[0]);
                $_max = count($v4) == 2 ? $v4[1] : ($v3[0] == "*" ? $max : $v3[0]);
                for ($i = $_min; $i <= $_max; $i += $step) {
                    $result[$i] = intval($i);
                }
            }
            ksort($result);
            return $result;
        }
    
        static protected function _parse_array($crontab_array, $start_time)
        {
            $result = array();
            foreach ($crontab_array as $val) {
                if(count(explode(":",$val)) == 2){
                    $val = $val.":01";
                }
                $time = strtotime($val);
                if ($time >= $start_time && $time < $start_time + 60) {
                    $result[$time] = $time;
                }
            }
            return $result;
        }
    }  

    line58:count($cron) == 5 如果满足条件的话,会返回[1=>1],会在插入tasktable

    public static function set_task($sec_list,$task){
    $time = time();
    foreach ($sec_list as $sec) {
    if($sec > 60){
    self::getInstance()->insert(array("tick"=>$sec,"task"=>$task));
    }else{
    self::getInstance()->insert(array("tick"=>$time+$sec,"task"=>$task));
    }
    }
    }
    会将1个任务加进task,time()+1s

    我们就讲解当个数为6的情况

    举例 * * * * **

    这种 不符合 */3 1-5这种类型的话会直接跳到行96,97 会计算出

    $v3[0] == "*" ? $min : $v3[0] $min = 0
    $v3[0] == "*" ? $max : $v3[0] $max = 59

    如果是*/3的话 

    $step = empty($v3[1]) ? 1 : $v3[1]; $step = 3;
    这样的话进制就会+3
    行98 for循环的话 就会生成 [0,3,6...57]

    如果是1-5的话

    $v4 = explode("-", $v3[0]); $v4=[1,5]
    $_min = count($v4) == 2 ? $v4[0] : ($v3[0] == "*" ? $min : $v3[0]); $_min = 1
    $_max = count($v4) == 2 ? $v4[1] : ($v3[0] == "*" ? $max : $v3[0]); $_max = 5
    行98 for循环的话 就会生成 [1,2,3,4,5]

    如果是1的话

    $v4 = explode("-", $v3[0]); $v4=[1]
    $_min = count($v4) == 2 ? $v4[0] : ($v3[0] == "*" ? $min : $v3[0]); count($v4)不等于2,会去判断$v3[0] == "*" 如果不等于会取$v3[0]取1

    $_max = count($v4) == 2 ? $v4[1] : ($v3[0] == "*" ? $max : $v3[0]); count($v4)不等于2,会去判断$v3[0] == "*" 如果不等于会取$v3[0]取1
    行98 for循环的话 就会生成 [1]


    得到结果值就会for循环写入到taskTabel中去,然后执行do_something
    
    
    
    




  • 相关阅读:
    JavaScript And Ajax(JavaScript 基本示例)
    JavaScript And Ajax(JavaScript 本质)
    LINQ(LINQ to Entities)
    XML (转换)
    XML 搜索和验证(XmlDocument、XPath to XmlDocument、LINQ to XDocument)
    图形、GDI + 和图表(Chart 控件)
    XML(简介)
    图形、GDI + 和图表(在网页上嵌入动态图形)
    网站导航(URL 映射和路由)
    JavaScript And Ajax(在客户端回调中使用 Ajax)
  • 原文地址:https://www.cnblogs.com/gavinjunftd/p/8080667.html
Copyright © 2011-2022 走看看