| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- <?php
- namespace common\components;
- use common\traits\ErrorTrait;
- /**
- * 解析定时任务
- * @Author bing
- * @DateTime 2021-10-11 18:14:42
- * @copyright: Copyright (c) 2020 广东七件事集团
- */
- class ParseCrontab
- {
- use ErrorTrait;
- /**
- * 解析crontab的定时格式,linux只支持到分钟/,这个类支持到秒
- *
- * @Author bing
- * @DateTime 2021-10-12 11:53:38
- * @copyright: Copyright (c) 2020 广东七件事集团
- * @param string $crontab_string
- * @param int $start_time
- * 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]
- * @throws InvalidArgumentException 错误信息
- * @return array|boolean
- */
- static public function parse($crontab_string, $start_time = null)
- {
- 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::setStaticError("Invalid cron string: " . $crontab_string);
- return false;
- }
- }
- if ($start_time && !is_numeric($start_time)) {
- self::setStaticError("\$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' => (empty($cron[0])) ? array(0 => 0) : 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) {
- if (intval($i) < $min) {
- $result[$min] = $min;
- } elseif (intval($i) > $max) {
- $result[$max] = $max;
- } else {
- $result[$i] = intval($i);
- }
- }
- }
- ksort($result);
- return $result;
- }
- }
|