scala解析linux crontab类型的时间,返回一个对应其含义的时间数组。

本文介绍了一种解析Linux Cron表达式的方法,通过自定义Scala函数将Cron格式转换为具体的时间数组,适用于需要定时任务配置的场景。同时,提供了一个使用SQL实现相同功能的示例,用于在数据库中筛选符合特定Cron表达式的记录。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

如果有错误,或者有可以改进的地方,请指出🙂 

/**
    * 获取linux crontab类型的时间,返回一个对应其含义的时间数组
    *数据样例 val timestr = """*;7,8-10,23;1,3-5,6;*"""  工作需要,我这只配置了时日月周
    * @param crontabStr
    */
  def parseCrontabTime(crontabStr: String): ArrayBuffer[String] = {
    val arrayBuffer = new ArrayBuffer[String]()
//切分出时间,在此我只取了 日 月
    val crontabargs = crontabStr.split("\\;")
    val daysargs = timeRange(crontabargs(1))
    val monthsargs = timeRange(crontabargs(2))

    for (i <- 0 until (monthsargs.length)) {
//找出单个数值的时间拼上0,不然就会成为不合规的时间格式,比如2020-6-1
      if (monthsargs(i).length == 1) {
        monthsargs(i) = "0" + monthsargs(i)
        //println(monthsargs(i))
      }
      for (j <- 0 until (daysargs.length)) {
        if (daysargs(j).length == 1) {
          daysargs(j) = "0" + daysargs(j)
        }
        arrayBuffer += TimeUntil.year() + "-" + monthsargs(i) + "-" + daysargs(j)

      }
    }
    arrayBuffer
  }


  /**
    * 经过第一次分号分隔后时间字符串的判断处理,也就是会单独摘出来 时 日 月 周
    *
    * @param timestr
    */

  private def timeRange(timestr: String): ArrayBuffer[String] = {
    val arrayBuffer = new ArrayBuffer[String]()
    val timeargs = timestr.split(",")
    //遍历每一个时间点如  1   7   9-15
    for (i <- 0 until timeargs.length) {
      //如果包含范围性时间9-15之类的再单独分一次,再加入到数组里
      if (isRegexpStr(timeargs(i))) {
        for (j <- timeargs(i).split("-")(0).toInt to timeargs(i).split("-")(1).toInt) {
          arrayBuffer += j.toString
        }
      }
      //否则没有范围性时间的话就直接加入到数组里
      else {
        arrayBuffer += timeargs(i)
      }

    }
    arrayBuffer

  }

  /**
    * 判断是否包含"-"的范围性时间
    *
    * @param timestr
    * @return
    */
  private def isRegexpStr(timestr: String): Boolean = {
    var boolean = false
    val strPattern = "[-]".r
    if (strPattern.findAllIn(timestr).length > 0) {
      boolean = true
    }
    boolean
  }

 

 

 

------------更新------------

其实用SQL也行。

描述下需求背景,我们需要用spark进行跑批任务,任务里有的是需要定时的,具体到天和月,比如每月十号跑,或者每个季度的某一天跑。然后我们有一张配置表,其中的定时任务字段就是linux里的样式  *;7,8-10,23;1,3-5,6;* 只不过用了分号分隔,大家也可以换别的。

select * from etl_table_config where 
case 
    when substring_index(substring_index(execution,';',2),';',-1) <> '*' -- 取得的日定时任务不等于*时,也就是有定时日跑的
        then
            if(day(curdate()) in (substring_index(substring_index(execution,';',2),';',-1)),true,
                if(substring_index(substring_index(execution,';',2),';',-1) regexp '-',
                    if(
                        -- 取出日范围区间的最小日
                        substring_index(substring_index(substring_index(substring_index(execution,';',2),';',-1),'-',1),',',-1)<=day(curdate())
                        and 
                        -- 取出日范围区间的最大日
                        substring_index(substring_index(substring_index(substring_index(execution,';',2),';',-1),'-',-1),',',1)>=day(curdate())
                        ,true
                        ,false
                    )
                   ,false
                   )
            )
    else true end
and 
case 
    when substring_index(substring_index(execution,';',-2),';',1) <> '*'    -- 取得的月定时任务不等于*时,也就是有定时月份跑的
        then
            if(month(curdate()) in (substring_index(substring_index(execution,';',-2),';',1)),true,
                if(substring_index(substring_index(execution,';',-2),';',1) regexp '-',
                    if(
                        -- 取出月范围区间的最小月
                        substring_index(substring_index(SUBSTRING_INDEX(SUBSTRING_INDEX(execution,';',-2),';',1),'-',1),',',-1)<=month(curdate())
                        and 
                        -- 取出月范围区间的最大月
                        substring_index(substring_index(SUBSTRING_INDEX(SUBSTRING_INDEX(execution,';',-2),';',1),'-',-1),',',1)>=month(curdate())
                        ,true
                        ,false
                    )
                   ,false
                   )
            )
    else true end -- 取得的月定时任务等于*时,也就是不需要定时月份跑
and
case 
    when substring_index(substring_index(execution,';',-3),';',-1) <> '*'    -- 取得的星期定时任务不等于*时,也就是有定时星期几跑的
        then
            if(WEEKDAY(curdate()) in (substring_index(substring_index(execution,';',-3),';',-1)),true,
                if(substring_index(substring_index(execution,';',-3),';',-1) regexp '-',
                    if(
                        -- 取出星期范围区间的最小星期
                        substring_index(substring_index(SUBSTRING_INDEX(SUBSTRING_INDEX(execution,';',-3),';',-1),'-',1),',',-1)<=WEEKDAY(curdate())
                        and 
                        -- 取出星期范围区间的最大星期
                        substring_index(substring_index(SUBSTRING_INDEX(SUBSTRING_INDEX(execution,';',-3),';',-1),'-',-1),',',1)>=WEEKDAY(curdate())
                        ,true
                        ,false
                    )
                   ,false
                   )
            )
    else true end -- 取得的月定时任务等于*时,也就是不需要定时月份跑

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值