<?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类,解析时间规则的更多相关文章

  1. Bootstrap 类解析

    Bootstrap 类解析 元素 Bootstrap 类 定义 <div> container 内容容器 <table> table 表格 <table> tabl ...

  2. 【Owin 学习系列】2. Owin Startup 类解析

    Owin Startup 类解析 每个 Owin 程序都有 startup 类,在这个 startup 类里面你可以指定应用程序管道模型中的组件.你可以通过不同的方式来连接你的 startup 类和运 ...

  3. Thrift compiler代码生成类解析

    代码生成类解析: Thrift--facebook RPC框架,介绍就不说了,百度,google一大把,使用也不介绍,直接上结构和分析吧. Hello.thrift文件内容如下: namespace ...

  4. SpringBoot入门(三)——入口类解析

    本文来自网易云社区 上一篇介绍了起步依赖,这篇我们先来看下SpringBoot项目是如何启动的. 入口类 再次观察工程的Maven配置文件,可以看到工程的默认打包方式是jar格式的. <pack ...

  5. Spark 资源调度包 stage 类解析

    spark 资源调度包 Stage(阶段) 类解析 Stage 概念 Spark 任务会根据 RDD 之间的依赖关系, 形成一个DAG有向无环图, DAG会被提交给DAGScheduler, DAGS ...

  6. 【Spring注解驱动开发】AOP核心类解析,这是最全的一篇了!!

    写在前面 昨天二狗子让我给他讲@EnableAspectJAutoProxy注解,讲到AnnotationAwareAspectJAutoProxyCreator类的源码时,二狗子消化不了了.这不,今 ...

  7. 【Python】-【类解析】--【脚本实例】

    通过脚本事例,解析下Python中类的几个概念在脚本中的应用 脚本如下: ++++++++++++++++++++++++++++++++++++++++ #!/usr/bin/env python# ...

  8. .net HTMLParser详细使用说明 强大的Filter类 解析HTML文档如此简单

    背景: HTMLParser原本是一个在sourceforge上的一个Java开源项目,使用这个Java类库可以用来线性地或嵌套地解析HTML文本.他的 功能强大和开源等特性吸引了大量Web信息提取的 ...

  9. Spring源码情操陶冶-AOP之Advice通知类解析与使用

    阅读本文请先稍微浏览下上篇文章Spring源码情操陶冶-AOP之ConfigBeanDefinitionParser解析器,本文则对aop模式的通知类作简单的分析 入口 根据前文讲解,我们知道通知类的 ...

随机推荐

  1. python批量操作Linux服务器脚本,ssh密码登录(执行命令、上传、下载)(一)

     -*-          paramiko.util.log_to_file(         ssh = paramiko.SSHClient()          ssh.set_missing ...

  2. 面试官提出的问题应该怎么答?(如开发中使用过EasyUI吗?)

    Jquery EasyUI是第三方基于Jquery框架开发的一款轻量级的,侧重于页面显示部分的框架,也可以称为插件. Jquery EasyUI使用比较简单,也有比较全的文档可供参考. 常用的组件就是 ...

  3. swift中的UITextField

    let userTF = UITextField(frame: CGRectMake(,,,)) userTF.backgroundColor = UIColor.redColor() // 输入框样 ...

  4. Monkey测试结果分析【转】

    转自[http://www.douban.com/note/257030241/] Monkey测试结果分析 一. 初步分析方法: Monkey测试出现错误后,一般的差错步骤为以下几步: 1. 找到是 ...

  5. Hadoop集群(四) Hadoop升级

    Hadoop前面安装的集群是2.6版本,现在升级到2.7版本. 注意,这个集群上有运行Hbase,所以,升级前后,需要启停Hbase. 更多安装步骤,请参考: Hadoop集群(一) Zookeepe ...

  6. vue-router,vuex

    vue设置路由为了服务器渲染今天换另一种方式首先在文件夹中router建立router和routes两个js文件,router用来设置路由,routes用来建立路由代码如下: router: impo ...

  7. Json Web Token JJWT

    什么是JWT? Json web token (JWT), 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准((RFC 7519).该token被设计为紧凑且安全的,特别适用于分布式站 ...

  8. 渲染Keynote

    [渲染Keynote] 1.渲染图元(rendering primitives),可以是点.线.三角. 2.显卡对于显存的访问速度更快,而且大多数显卡对于RAM没有直接的访问权利 . 3.裁剪(Cli ...

  9. python-ceilometerclient命令行(2)

    命令行解析工具argparse argparse是python标准库中的模块,利用argparse,可以完成对命令行的参数定义.解析以及后续的处理.一个简单的例子: # coding:utf-8 im ...

  10. Unity&UGUI

    UI:User Interface 用户交互接口,处理用户与程序直接的交互 新建一个UI控件,都会同时新建两个物体: --Canvas:画布,所有的UI控件都必须放到画布上 --EnventSyste ...