module IceCube::Validations::Lock

This validation mixin is used by the various “fixed-time” (e.g. day, day_of_month, hour_of_day) Validation and ScheduleLock::Validation modules. It is not a standalone rule validation like the others.

Given the including Validation’s defined type field, it will lock to the specified value or else the corresponding time unit from the schedule’s start_time

Constants

INTERVALS

Public Instance Methods

validate(time, start_time) click to toggle source
# File lib/ice_cube/validations/lock.rb, line 15
def validate(time, start_time)
  case type
  when :day  then validate_day_lock(time, start_time)
  when :hour then validate_hour_lock(time, start_time)
  else validate_interval_lock(time, start_time)
  end
end

Private Instance Methods

starting_unit(start_time) click to toggle source
# File lib/ice_cube/validations/lock.rb, line 87
def starting_unit(start_time)
  start = value || start_time.send(type)
  start += INTERVALS[type] while start < 0
  start
end
validate_day_lock(time, start_time) click to toggle source

For monthly rules that have no specified day value, the validation relies on the schedule start time and jumps to include every month even if it has fewer days than the schedule’s start day.

Negative day values (from month end) also include all months.

Positive day values are taken literally so months with fewer days will be skipped.

# File lib/ice_cube/validations/lock.rb, line 60
def validate_day_lock(time, start_time)
  days_in_month = TimeUtil.days_in_month(time)
  date = Date.new(time.year, time.month, time.day)

  if value && value < 0
    start = TimeUtil.day_of_month(value, date)
    month_overflow = days_in_month - TimeUtil.days_in_next_month(time)
  elsif value && value > 0
    start = value
    month_overflow = 0
  else
    start = TimeUtil.day_of_month(start_time.day, date)
    month_overflow = 0
  end

  sleeps = start - date.day

  if value && value > 0
    until_next_month = days_in_month + sleeps
  else
    until_next_month = start < 28 ? days_in_month : TimeUtil.days_to_next_month(date)
    until_next_month += sleeps - month_overflow
  end

  sleeps >= 0 ? sleeps : until_next_month
end
validate_hour_lock(time, start_time) click to toggle source

Lock the hour if explicitly set by hour_of_day, but allow for the nearest hour during DST start to keep the correct interval.

# File lib/ice_cube/validations/lock.rb, line 37
def validate_hour_lock(time, start_time)
  h0 = starting_unit(start_time)
  h1 = time.hour
  if h0 >= h1
    h0 - h1
  else
    if dst_offset = TimeUtil.dst_change(time)
      h0 - h1 + dst_offset
    else
      24 - h1 + h0
    end
  end
end
validate_interval_lock(time, start_time) click to toggle source

Validate if the current time unit matches the same unit from the schedule start time, returning the difference to the interval

# File lib/ice_cube/validations/lock.rb, line 28
def validate_interval_lock(time, start_time)
  t0 = starting_unit(start_time)
  t1 = time.send(type)
  t0 >= t1 ? t0 - t1 : INTERVALS[type] - t1 + t0
end