class BBLib::Cron
Constants
- PARTS
- REPLACE
- SPECIAL_EXP
Attributes
parts[R]
Public Class Methods
next(exp, count: 1, time: Time.now)
click to toggle source
# File lib/bblib/classes/cron.rb, line 26 def self.next(exp, count: 1, time: Time.now) BBLib::Cron.new(exp).next(count: count, time: time) end
numeralize(exp)
click to toggle source
# File lib/bblib/classes/cron.rb, line 42 def self.numeralize(exp) REPLACE.each do |k, v| v.each do |r| exp = exp.to_s.gsub(r.to_s, k.to_s) end end exp end
prev(exp, count: 1, time: Time.now)
click to toggle source
# File lib/bblib/classes/cron.rb, line 30 def self.prev(exp, count: 1, time: Time.now) BBLib::Cron.new(exp).prev(count: count, time: time) end
valid?(exp)
click to toggle source
# File lib/bblib/classes/cron.rb, line 34 def self.valid?(exp) !(numeralize(exp) =~ /\A(.*?\s){4,5}.*?\S\z/).nil? end
Public Instance Methods
expression=(e)
click to toggle source
# File lib/bblib/classes/cron.rb, line 18 def expression=(e) e = e.to_s.downcase SPECIAL_EXP.each { |x, v| e = x if v.include?(e) } @expression = e parse e end
next(exp = expression, count: 1, time: Time.now)
click to toggle source
# File lib/bblib/classes/cron.rb, line 8 def next(exp = expression, count: 1, time: Time.now) self.expression = exp unless exp == expression closest(count: count, time: time, direction: 1) end
prev(exp = expression, count: 1, time: Time.now)
click to toggle source
# File lib/bblib/classes/cron.rb, line 13 def prev(exp = expression, count: 1, time: Time.now) self.expression = exp unless exp == expression closest(count: count, time: time, direction: -1) end
time_match?(time)
click to toggle source
# File lib/bblib/classes/cron.rb, line 51 def time_match?(time) (@parts[:minute].empty? || @parts[:minute].include?(time.min)) && (@parts[:hour].empty? || @parts[:hour].include?(time.hour)) && (@parts[:day].empty? || @parts[:day].include?(time.day)) && (@parts[:weekday].empty? || @parts[:weekday].include?(time.wday)) && (@parts[:month].empty? || @parts[:month].include?(time.month)) && (@parts[:year].empty? || @parts[:year].include?(time.year)) end
valid?(exp)
click to toggle source
# File lib/bblib/classes/cron.rb, line 38 def valid?(exp) BBLib::Cron.valid?(exp) end
Private Instance Methods
closest(direction: 1, count: 1, time: Time.now)
click to toggle source
# File lib/bblib/classes/cron.rb, line 95 def closest(direction: 1, count: 1, time: Time.now) return unless @expression results = (1..count).flat_map do |_i| time = next_time(time + 60 * direction, direction) end count <= 1 ? results.first : results.compact end
next_day(time, direction)
click to toggle source
# File lib/bblib/classes/cron.rb, line 132 def next_day(time, direction) return time if @parts[:day].empty? time += 24*60*60 * direction until @parts[:day].include?(time.day) time end
next_hour(time, direction)
click to toggle source
# File lib/bblib/classes/cron.rb, line 122 def next_hour(time, direction) return time if @parts[:hour].empty? until @parts[:hour].include?(time.hour) time -= time.min * 60 if direction.positive? time += (59 - time.min) * 60 if direction.negative? time += 60*60 * direction end time end
next_min(time, direction)
click to toggle source
# File lib/bblib/classes/cron.rb, line 116 def next_min(time, direction) return time if @parts[:minute].empty? time += 60 * direction until @parts[:minute].include?(time.min) time end
next_month(time, direction)
click to toggle source
# File lib/bblib/classes/cron.rb, line 144 def next_month(time, direction) return time if @parts[:month].empty? until @parts[:month].include?(time.month) original = time.month min = direction.positive? ? 0 : 59 hour = direction.positive? ? 0 : 23 day = direction.positive? ? 1 : 31 month = BBLib.loop_between(time.month + direction, 1, 12) year = if direction.positive? && month == 1 time.year + 1 elsif direction.negative? && month == 12 time.year - 1 else time.year end time = Time.new(year, month, day, hour, min) if direction.negative? && time.month == original time -= 24 * 60 * 60 while time.month == original end end time end
next_time(time, direction)
click to toggle source
# File lib/bblib/classes/cron.rb, line 103 def next_time(time, direction) original = time.dup safety = 0 methods = [:next_year, :next_month, :next_weekday, :next_day, :next_hour, :next_min] until safety >= 1_000_000 || time_match?(time) methods.each do |sym| time = send(sym, time, direction) end safety += 1 end time - (time.sec.zero? ? 0 : original.sec) end
next_weekday(time, direction)
click to toggle source
# File lib/bblib/classes/cron.rb, line 138 def next_weekday(time, direction) return time if @parts[:weekday].empty? time += 24*60*60 * direction until @parts[:weekday].include?(time.wday) time end
next_year(time, direction)
click to toggle source
# File lib/bblib/classes/cron.rb, line 167 def next_year(time, direction) return time if @parts[:year].empty? until @parts[:year].include?(time.year) day = direction.positive? ? 1 : 31 hour = direction.positive? ? 0 : 23 min = direction.positive? ? 0 : 59 month = direction.positive? ? 1 : 12 time = Time.new(time.year + direction, month, day, hour, min) end time end
parse()
click to toggle source
# File lib/bblib/classes/cron.rb, line 67 def parse @parts = {} PARTS.keys.zip(@expression.split(' ')).to_h.each do |part, piece| info = PARTS[part] @parts[part] = parse_cron_numbers(piece, info[:min], info[:max], Time.now.send(info[:send])) end end
parse_cron_numbers(exp, min, max, qmark)
click to toggle source
# File lib/bblib/classes/cron.rb, line 75 def parse_cron_numbers(exp, min, max, qmark) numbers = [] return numbers if exp == '*' exp = Cron.numeralize(exp).gsub('?', qmark.to_s).gsub('*', "#{min}-#{max}") exp.scan(/\*\/\d+|\d+\/\d+|\d+-\d+\/\d+/).each do |s| range = s.split('/').first.split('-').map(&:to_i) + [max] divisor = s.split('/').last.to_i Range.new(*range[0..1]).each_with_index do |i, index| numbers.push(i) if index.zero? || (index % divisor).zero? end exp = exp.sub(s, '') end exp.scan(/\d+\-\d+/).each do |e| nums = e.scan(/\d+/).map(&:to_i) numbers.push(Range.new(*nums).to_a) end numbers.push(exp.scan(/\d+/).map(&:to_i)) numbers.flatten.uniq.sort.reject { |r| r < min || r > max } end
simple_init(*args)
click to toggle source
# File lib/bblib/classes/cron.rb, line 62 def simple_init(*args) @parts = {} self.expression = args.first if args.first.is_a?(String) end