lib/ice_cube_ex/rules/day_cycle_rule.rb
require 'ice_cube_ex/validations/day_cycle_interval'
module IceCubeEx
class DayCycleRule < IceCube::ValidatedRule
include Validations::DayCycleInterval
def initialize(cycle, skip)
super
cycle(cycle, skip)
schedule_lock(:hour, :min, :sec)
reset
end
# given the following case:
#
# Schedule start_time 2014-2-2, DayCycleRule with cycle 4, skip 2
#
# if we invoke schedule.next_occurrence(2014-2-1), first calculated
# time will be 2014-2-2, which will give a day_count of 0, thus being lower
# than cycle_percentage and being a valid value.
# this by itself is not a problem, but it will ruin our cycle logic since
# only for the first case it will repeat 3 times instead of 2, because
# the following dates will be valid:
#
# 2014-2-2, 2014-2-3, 2014-2-4
#
# so to avoid this we start counting from start_time - 1.day (cycle_start_time)
def next_time(time, schedule, closing_time)
@time = time
@schedule = schedule
cycle_start_time = schedule.start_time - 24 * 60 * 60
return nil unless find_acceptable_time_before(closing_time)
number_of_days = number_of_days_between(@time, cycle_start_time)
current_cycle_percentage = calculate_percentage(number_of_days)
until current_cycle_percentage <= @acceptable_cycle_percentage
@time += 1
return nil unless find_acceptable_time_before(closing_time)
number_of_days = number_of_days_between(@time, cycle_start_time)
current_cycle_percentage = calculate_percentage(number_of_days)
end
@uses += 1 if @time
@time
end
def number_of_days_between(acceptable_time, initial_time)
acceptable_time_date = get_date(acceptable_time)
initial_time_date = get_date(initial_time)
((acceptable_time_date - initial_time_date) / (24 * 60 * 60)).to_i
end
def get_date(time)
Time.new(time.year, time.month, time.day, 0, 0, 0, '+00:00')
end
def calculate_percentage(day_count)
value = (day_count.to_f / @cycle.to_f)
percentage = ((value - value.to_i) * 100).to_i
percentage.zero? ? 100 : percentage
end
end
end