Module: Patriot::Util::CronFormatParser

Included in:
Tool::BatchParser
Defined in:
lib/patriot/util/cron_format_parser.rb

Overview

module for handling cron format interval

Constant Summary collapse

DEFAULT_CRON_FIELD =

start 00:00:00 everyday

"0 0 * * *"
END_OF_EVERY_MONTH =

a key word to indicate interval in which jobs are executed on the end of every month

'end_of_every_month'
WEEKS =

the list of week days

0.upto(6).to_a
MONTHS =

the list of months

1.upto(12).to_a
DAYS =

the list of days

1.upto(31).to_a
HOURS =

the list of hours

0.upto(23).to_a
MINUTES =

the list of minutes

0.upto(59).to_a
DAY_IN_SECOND =
60 * 60 * 24

Instance Method Summary collapse

Instance Method Details

#expand_on_date(date, cron_field = nil) ⇒ Array<Time>

expand a given date to the array of time which should be executed in case of a given cron field

Parameters:

  • date (Time)

    target datetime

  • cron_field (String) (defaults to: nil)

    interval in cron format

Returns:

  • (Array<Time>)

    a list of datetime which match the cron format



30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
# File 'lib/patriot/util/cron_format_parser.rb', line 30

def expand_on_date(date, cron_field = nil)
  cron_field = DEFAULT_CRON_FIELD if cron_field.nil? || cron_field.empty?
  if cron_field == END_OF_EVERY_MONTH
    return (date + DAY_IN_SECOND).day == 1 ? [date] : []
  end
  field_splits = cron_field.split
  raise "illegal cron field format #{cron_field}" unless field_splits.size == 5
  minute, hour, day, month, week = field_splits
  return [] unless is_target_day?(date, day, month, week)
  return target_hours(hour).map do |h|
    target_minutes(minute).map do |m|
      Time.new(date.year, date.month, date.day, h, m, 0)
    end
  end.flatten
end

#is_target_day?(date, day, month, week) ⇒ Boolean

check a given date is a target or not

Parameters:

  • date (Time)

    a datetime to be checked

  • day (String)

    day field in cron format

  • month (String)

    month field in cron format

  • week (String)

    week field in cron format

Returns:

  • (Boolean)


51
52
53
54
55
56
57
58
59
# File 'lib/patriot/util/cron_format_parser.rb', line 51

def is_target_day?(date, day, month, week)
  unless month == "*" || parse_field(month, MONTHS).to_a.include?(date.month)
    return false 
  end
  return true if day == "*" && week == "*"
  target_weeks = parse_field(week, WEEKS)
  return parse_field(day, DAYS).include?(date.day) if week == "*"
  return parse_field(week, WEEKS).include?(date.wday)
end

#parse_field(field, domain) ⇒ Array<Integer>

select elements which match a given field from a given domain

Parameters:

  • field (String)

    one of the cron field

  • domain (Array<Integer>)

    the domain of the field

Returns:

  • (Array<Integer>)

    a list of the domain elements match with the field



77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
# File 'lib/patriot/util/cron_format_parser.rb', line 77

def parse_field(field, domain)
  field = field.split("/")
  raise "illegal cron field format #{field.join("/")}" unless field.size <= 2 
  range = []
  if field[0] == "*"
    range = domain 
  else
    range = field[0].split(",").map do |r|
      subrange = r.split("-")
      if subrange.size == 1
        subrange[0].to_i
      elsif subrange.size == 2 
        subrange[0].to_i.upto(subrange[1].to_i).to_a
      else
        raise "illegal cron field format #{field.join("/")}" 
      end
    end.flatten
  end
  return range if field.size == 1
  interval = field[1].to_i
  filtered_range = []
  range.each_with_index do |r,i| 
    filtered_range << r if (i % interval) == 0
  end
  return filtered_range
end

#target_hours(hour) ⇒ Array<Integer>

Returns a target hours for the given hour specification.

Parameters:

  • hour (String)

    hour field in cron format

Returns:

  • (Array<Integer>)

    a target hours for the given hour specification



63
64
65
# File 'lib/patriot/util/cron_format_parser.rb', line 63

def target_hours(hour)
  return parse_field(hour, HOURS)
end

#target_minutes(minute) ⇒ Array<Integer>

Returns a target minutes for the given minute specification.

Parameters:

  • minute (String)

    minute field in cron format

Returns:

  • (Array<Integer>)

    a target minutes for the given minute specification



69
70
71
# File 'lib/patriot/util/cron_format_parser.rb', line 69

def target_minutes(minute)
  return parse_field(minute, MINUTES)
end