ParseCrontab类,解析时间规则

摘要:
$start_time=null){if(is_array($crontab_string)){returnself,$start_time):is_numeric($start_tme)){self;trim($crontab_string):$start=empty($start_time):$sstart_time;
<?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




免责声明:文章转载自《ParseCrontab类,解析时间规则》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇submile text3常用快捷键[java]创建一个默认TreeMap() key为什么不能为null下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

记一次Postgresql异常中断导致的启动失败

由于异常导致了测试服务器的Pg11宕机,启动时候报错 2019-06-11 14:20:08.121 CST [9980] 致命错误: 数据库系统启动中 2019-06-11 14:20:08.121 CST [9981] 致命错误: 数据库系统启动中 2019-06-11 14:20:08.121 CST [9964] 致命错误: 数据库系统启动中...

Java 实例 – 数组添加元素

[ Java 实例 - 数组添加元素 Java 实例 以下实例演示了如何使用sort()方法对Java数组进行排序,及如何使用 insertElement () 方法向数组插入元素, 这边我们定义了 printArray() 方法来打印数组: MainClass.java 文件 import java.util.Arrays; public c...

LINUX下简单的编译和使用动态链接库[compile .so use c++ in linux]

对动态链接库的概念其实还很模糊,自己的理解是:把一些常用的代码,如函数,类等,编译成一个"包"即DLL(WINDOWS下)或者SO(LINUX下)文件,然后供其它程序使用时直接调用里面封闭的函数即可,实现的代码的重用,也节省了硬盘空间(这点可能是次要的吧).在WIDOWS下利用VC++可方便的生成DLL,在LINUX下则需要通过各种编译命令来实现,对于像我...

springmvc 后端入口参数接收

package controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.R...

Restful API 设计参考原则

在项目中,需要为后台服务撰写API。刚开始接触的时候,并没有考虑太多,就想提供URL,服务端通过该URL进行查询、创建、更新等操作即可。但再对相关规范进行了解后,才发现,API的设计并没有那么简单,远远不是URL的问题,而是一个通信协议的整体架构 1. 使用GET、POST、PUT、DELETE这几种请求模式 请求模式也可以说是动作、数据传输方式,通常我们...

Django之缓存、信号和图片验证码、ORM性能

一、 缓存 1、 介绍 缓存通俗来说:就是把数据先保存在某个地方,下次再读取的时候不用再去原位置读取,让访问速度更快。 缓存机制图解 2、Django中提供了6种缓存方式   1. 开发调试   2. 内存   3. 文件   4. 数据库   5. Memcache缓存(python-memcached模块)   6. Memcache缓存(pyl...