将cron转换为R中的时间戳

时间:2012-10-12 08:39:58

标签: r crontab cronexpression

我正在寻找一种方法,使用R将cron信息转换为时间戳列表。 有简单的方法吗?

鉴于crontab以及开始日期和结束日期,我想在这两个日期获取触发时间戳列表。

我还没有找到任何专门处理CRON信息的软件包,但也许有人已经遇到过这个问题?

由于

1 个答案:

答案 0 :(得分:2)

我认为你的意思是crontab(5)格式。我知道没有库解析这些信息,但下面的代码片段应该让你开始:

splitre <- function(p, s) {
  s <- as.character(s)
  stopifnot(length(s) == 1)
  m <- gregexpr(p, s)[[1]]
  if (m[1] == -1) return(s);
  return(substring(s, c(1, m + attr(m, "match.length")), c(m - 1, nchar(s))))
}

ranges <- function(desc, lo, hi, name) {
  res <- integer(0)
  for (range in splitre(",", desc)) {
    m <- regexec("^(?:\\*|(?:(\\d+)(?:-(\\d+))?))(?:/(\\d+))?$", range)
    m <- regmatches(range, m)[[1]]
    m[m == ""] <- NA
    m[1] <- NA
    m <- as.integer(m)
    if (is.na(m[2])) r <- lo:hi
    else if (is.na(m[3])) r <- m[2]
    else r <- m[2]:m[3]
    if (!is.na(m[4])) {
      stopifnot(m[4] > 0)
      r <- r[rep(c(TRUE, rep(FALSE, m[4] - 1)), length.out = length(r))]
    }
    res <- c(res, r)
  }
  res <- data.frame(res)
  names(res) <- name
  return(res)
}

ct2df <- function(lines) {
  res <- data.frame()
  for (line in lines) {
    if (regexpr("^ *(#|$)", line) == 1) continue
    parts <- splitre(" +", line)
    stopifnot(length(parts) > 5)
    j <- ranges(parts[1], 0, 59, "minute")
    j <- merge(j, ranges(parts[2], 0, 23, "hour"))
    j <- merge(j, ranges(parts[3], 1, 31, "day.of.month"))
    j <- merge(j, ranges(parts[4], 1, 12, "month"))
    j <- merge(j, ranges(parts[5], 0, 6, "day.of.week"))
    res <- rbind(res, j)
  }
  return(res)
}

print(ct2df("* 1-2,5 1-10/2 */3 1 command"))

这并不完美,因为它不会处理几个月或一周中的名字,并且它不会处理关于日期与星期几的特殊情况,这需要*的处理不仅仅是一个简单的范围。

  

注意:命令执行的日期可以由两个字段指定 - 月中的某天和星期几。如果两个字段都受限制(即,不是*),则当任一字段与当前时间匹配时,将运行该命令。例如,30 4 1,15 * 5将导致命令在每个月的1日和15日凌晨4:30以及每个星期五运行。

结果数据框可以转换为时间戳列表,但我没有为此编写代码。也许其他人会在这篇文章的基础上建立。简单但缓慢的方法是逐个迭代可能的时间戳,对于每个时间戳,查看计算数据帧中的行是否与该值匹配。更快的解决方案将逐日迭代,使用它来计算星期几和星期几,然后从与当天匹配的所有行中抽出时间。