当前位置:首页 > 程序心得 > 正文内容

php解析crontab时间格式

admin5年前 (2020-07-15)程序心得1699

crontab 时间格式:


配置说明

“* * * * * *”分 时 日 月 周

“0 3 * * * *”数字精确配置, 星号为任意.(每天凌晨3点整)

“15,30 3 * * *”逗号表示枚举 (每天3点15分和3点30分)

“15-30 3 * * *”短线表示范围 (每天的3点15分到30分)

“*/10 3 * * *”斜杠表示间隔 (每天3点0分到30分之间, 每10分钟一次)

“0-10,50-59/2 3 * * *”优先级:枚举>范围>间隔 (每天3点0分到10分以及50到59分期间, 每2分钟一次)

注意:不支持解析以英文名称配置的时间计划(如:”0 4 1 jan “)


应用场景: crontab配置一个php, 然后由php管理多个php的crontab任务

<?php
/**
* @file: Crontab.php
* @author: yuyunhe@zuoyebang.com
* @date: 2020/7/15 17:30
*/

//crontab 时间格式:
//
//配置   说明
//“* * * * * *”    分 时 日 月 周
//“0 3 * * * *”    数字精确配置, 星号为任意.(每天凌晨3点整)
//“15,30 3 * * *”  逗号表示枚举 (每天315分和330)
//“15-30 3 * * *”  短线表示范围 (每天的315分到30)
//“*/10 3 * * *”   斜杠表示间隔 (每天30分到30分之间, 10分钟一次)
//“0-10,50-59/2 3 * * *”   优先级:枚举>范围>间隔 (每天30分到10分以及5059分期间, 2分钟一次)
//注意:不支持解析以英文名称配置的时间计划(:”0 4 1 jan “)

/**
* crontab 时间格式php解析类(PHP 5 >= 5.1.0)
*
*/
class OpCloud_CronTab
{

   /**
    * 检查某时间($time)是否符合某个corntab时间计划($str_cron)
    *
    * @param int $time 时间戳
    * @param string $str_cron corntab的时间计划,如,"30 2 * * 1-5"
    *
    * @return bool/string 出错返回string(错误信息)
    */
   static public function check($time, $str_cron)
   {
       $format_time = self::format_timestamp($time);
       $format_cron = self::format_crontab($str_cron);
       if (!is_array($format_cron)) {
           return $format_cron;
       }
       return self::format_check($format_time, $format_cron);
   }

   /**
    * 使用格式化的数据检查某时间($format_time)是否符合某个corntab时间计划($format_cron)
    *
    * @param array $format_time self::format_timestamp()格式化时间戳得到
    * @param array $format_cron self::format_crontab()格式化的时间计划
    *
    * @return bool
    */
   static public function format_check(array $format_time, array $format_cron)
   {
       return (!$format_cron[0] || in_array($format_time[0], $format_cron[0]))
           && (!$format_cron[1] || in_array($format_time[1], $format_cron[1]))
           && (!$format_cron[2] || in_array($format_time[2], $format_cron[2]))
           && (!$format_cron[3] || in_array($format_time[3], $format_cron[3]))
           && (!$format_cron[4] || in_array($format_time[4], $format_cron[4]));
   }

   /**
    * 格式化时间戳,以便比较
    *
    * @param int $time 时间戳
    *
    * @return array
    */
   static public function format_timestamp($time)
   {
       return explode('-', date('i-G-j-n-w', $time));
   }

   /**
    * 格式化crontab时间设置字符串,用于比较
    *
    * @param string $str_cron crontab的时间计划字符串,如"15 3 * * *"
    *
    * @return array/string 正确返回数组,出错返回字符串(错误信息)
    */
   static public function format_crontab($str_cron)
   {
       //格式检查
       $str_cron = trim($str_cron);
       $reg      = '#^((\*(/\d+)?|((\d+(-\d+)?)(?3)?)(,(?4))*))( (?2)){4}$#';
       if (!preg_match($reg, $str_cron)) {
           return '格式错误';
       }

       try {
           //分别解析分、时、日、月、周
           $arr_cron    = [];
           $parts       = explode(' ', $str_cron);
           $arr_cron[0] = self::parse_cron_part($parts[0], 0, 59);//
           $arr_cron[1] = self::parse_cron_part($parts[1], 0, 59);//
           $arr_cron[2] = self::parse_cron_part($parts[2], 1, 31);//
           $arr_cron[3] = self::parse_cron_part($parts[3], 1, 12);//
           $arr_cron[4] = self::parse_cron_part($parts[4], 0, 6);//周(0周日)
       } catch (Exception $e) {
           return $e->getMessage();
       }

       return $arr_cron;
   }

   /**
    * 解析crontab时间计划里一个部分(分、时、日、月、周)的取值列表
    * @param string $part 时间计划里的一个部分,被空格分隔后的一个部分
    * @param int $f_min 此部分的最小取值
    * @param int $f_max 此部分的最大取值
    *
    * @return array 若为空数组则表示可任意取值
    * @throws Exception
    */
   static protected function parse_cron_part($part, $f_min, $f_max)
   {
       $list = [];

       //处理"," -- 列表
       if (false !== strpos($part, ',')) {
           $arr = explode(',', $part);
           foreach ($arr as $v) {
               $tmp  = self::parse_cron_part($v, $f_min, $f_max);
               $list = array_merge($list, $tmp);
           }
           return $list;
       }

       //处理"/" -- 间隔
       $tmp  = explode('/', $part);
       $part = $tmp[0];
       $step = isset($tmp[1]) ? $tmp[1] : 1;

       //处理"-" -- 范围
       if (false !== strpos($part, '-')) {
           [$min, $max] = explode('-', $part);
           if ($min > $max) {
               throw new Exception('使用"-"设置范围时,左不能大于右');
           }
       } elseif ('*' == $part) {
           $min = $f_min;
           $max = $f_max;
       } else {//数字
           $min = $max = $part;
       }

       //空数组表示可以任意值
       if ($min == $f_min && $max == $f_max && $step == 1) {
           return $list;
       }

       //越界判断
       if ($min < $f_min || $max > $f_max) {
           throw new Exception('数值越界。应该:分0-59,时0-59,日1-31,月1-12,周0-6');
       }

       return $max - $min > $step ? range($min, $max, $step) : [(int)$min];
   }
}


分享到:

扫描二维码推送至手机访问。

版权声明:本文由云河空间发布,如需转载请注明出处。

本文链接:http://yuyunhe.cn/index.php/post/302.html

分享给朋友:

“php解析crontab时间格式” 的相关文章

Thinkphp3.2.x 多图上传几个注意点

1、<form enctype="multipart/form-data">2、<form enctype="multipart/form-data">3、<input type="file...

解决在微信内分享第三方链接标题、图片、摘要、链接等问题

<script src="http://res.wx.qq.com/open/js/jweixin-1.0.0.js"></script> <script> var imgUrl = docum...

Mysql 触发器使用(含navicat使用案例)

Mysql 触发器使用(含navicat使用案例)

CREATE TRIGGER updateutime2 BEFORE UPDATE on yp_cms_score for EACH ROW BEGIN  SET NEW.utime= ...

多行文字溢出[...]的实现(text-overflow: ellipsis)

多行文字溢出[...]的实现(text-overflow: ellipsis)

对于单行文字, 很简单. Css代码  .oneLine {      width: 200px;      overflow:&...

css做屏幕适配

CSS判断不同分辨率浏览器(显示屏幕)显示不同宽度布局CSS3技术支持IE6到IE8。将用到css3 @media样式进行判断,但IE9以下版本不支持CSS3技术,这里DIVCSS5给大家介绍通过JS实现低版本的浏览器也支持CSS3实现实用布局CSS DIV网页布局中当分辨率小于等于1024px(像...

RSA密钥的生成与配置(支付宝公私密钥可用)

RSA密钥的生成与配置(支付宝公私密钥可用)

RSA密钥的生成与配置openssl下载地址http://dldx.csdn.net/fd.php?i=20313208579480&s=ac2e809e168f7d5b8bf1515d3d6b1aa4,或者官方下载通过openssl工具生成RSA的公钥和私钥(opnssl工具可在互联网中下...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。