class CronParser

Constants

SUBELEMENT_REGEX

Public Instance Methods

parse_element(elem, allowed_range, time_specs_key=nil) click to toggle source
# File lib/cron_parse.rb, line 8
def parse_element(elem, allowed_range, time_specs_key=nil)
  values = elem.split(',').map do |subel|
    if subel =~ /^\*/
      step = subel.length > 1 ? subel[2..-1].to_i : 1
      stepped_range(allowed_range, step)
    else
      if SUBELEMENT_REGEX === subel
        if $6 # with range
          stepped_range($1.to_i..$4.to_i, $6.to_i)
        elsif $4 # range without step
          stepped_range($1.to_i..$4.to_i, 1)
        elsif $1 == "l" && time_specs_key == :dom
          [$1]
        elsif $1 == "w" && time_specs_key == :dow
          [1, 2, 3, 4, 5]
        else # just a numeric
          @dow_offset = $7.to_i if $7
          [$1.to_i]
        end
      else
        raise ArgumentError, "Bad Vixie-style specification #{subel}"
      end
    end
  end.flatten

  values = values.sort if time_specs_key.nil?
  [Set.new(values), values, elem]
end

Protected Instance Methods

interpolate_weekdays_without_cache(year, month) click to toggle source
# File lib/cron_parse.rb, line 62
def interpolate_weekdays_without_cache(year, month)
  t = Date.new(year, month, 1)
  valid_mday, _, mday_field = time_specs[:dom]
  valid_wday, _, wday_field = time_specs[:dow]
  # Careful, if both DOW and DOM fields are non-wildcard,
  # then we only need to match *one* for cron to run the job:
  if not (mday_field == '*' and wday_field == '*')
    valid_mday = [] if mday_field == '*'
    valid_wday = [] if wday_field == '*'
  end
  # Careful: crontabs may use either 0 or 7 for Sunday:
  valid_wday << 0 if valid_wday.include?(7)

  # Now only handle "L" statement
  valid_mday << (t.next_month - 1).day if valid_mday.include?("l")

  result = []
  while t.month == month
    result << t.mday if valid_mday.include?(t.mday) || valid_wday.include?(t.wday)
    t = t.succ
  end

  [Set.new(result), result]
end
nudge_date(t, dir = :next, can_nudge_month = true) click to toggle source
# File lib/cron_parse.rb, line 39
def nudge_date(t, dir = :next, can_nudge_month = true)
  spec = interpolate_weekdays(t.year, t.month)[1]
  spec = [spec[@dow_offset-1]] if @dow_offset

  next_value = find_best_next(t.day, spec, dir)
  t.day = next_value || (dir == :next ? spec.first : spec.last)

  nudge_month(t, dir) if next_value.nil? && can_nudge_month
end
nudge_month(t, dir = :next) click to toggle source
# File lib/cron_parse.rb, line 49
def nudge_month(t, dir = :next)
  spec = time_specs[:month][1]
  next_value = find_best_next(t.month, spec, dir)
  t.month = next_value || (dir == :next ? spec.first : spec.last)

  nudge_year(t, dir) if next_value.nil?

  # we changed the month, so its likely that the date is incorrect now
  valid_days = interpolate_weekdays(t.year, t.month)[1]
  valid_days = [valid_days[@dow_offset-1]] if @dow_offset
  t.day = dir == :next ? valid_days.first : valid_days.last
end
time_specs() click to toggle source
# File lib/cron_parse.rb, line 87
def time_specs
  @time_specs ||= begin
    # tokens now contains the 5 fields
    tokens = substitute_parse_symbols(@source).split(/\s+/)
    {
      :minute => parse_element(tokens[0], 0..59), #minute
      :hour   => parse_element(tokens[1], 0..23), #hour
      :dom    => parse_element(tokens[2], 1..31, :dom), #DOM
      :month  => parse_element(tokens[3], 1..12), #mon
      :dow    => parse_element(tokens[4], 0..6, :dow) #DOW
    }
  end
end