class SayWhen::DaysOfWeekCronValue

Constants

DAYS

Attributes

is_last[RW]
is_specified[RW]
nth_day[RW]

Public Class Methods

new(exp) click to toggle source
Calls superclass method SayWhen::CronValue::new
# File lib/say_when/cron_expression.rb, line 404
def initialize(exp)
  self.is_last = false
  super(:wday, 1, 7, exp)
end

Public Instance Methods

include?(date) click to toggle source
# File lib/say_when/cron_expression.rb, line 423
def include?(date)
  return true unless is_specified
  if is_last
    last = last_wday(date, values.first).to_date
    date.to_date == last
  elsif nth_day
    date.to_date == nth_wday(nth_day, values.first, date.month, date.year).to_date
  else
    values.include?(date.wday + 1)
  end
end
last(date) click to toggle source
# File lib/say_when/cron_expression.rb, line 435
def last(date)
  last_dow = if !is_specified
    date
  elsif is_last
    last = last_wday(date, values.first)
    if last.to_date > date.to_date
      last = last_wday(1.month.ago(date).change(day: 1), values.first)
    end
    last
  elsif nth_day
    nth = nth_wday(nth_day, values.first, date.month, date.year)
    if nth.to_date > date.to_date
      nth = 1.month.ago(date).change(day: 1)
      nth = nth_wday(nth_day, values.first, nth.month, nth.year)
    end
    nth
  else
    n = values.detect { |v| v > date.wday }
    n = values[0] if n.blank?
    base = (n < (date.wday + 1)) ? 7 : 0
    days_forward = n + (base - (date.wday + 1))
    days_forward.days.since(date)
  end
  last_dow.change(hour: 23, min: 59, sec: 59)
end
last_wday(date, aWday) click to toggle source
# File lib/say_when/cron_expression.rb, line 487
def last_wday(date, aWday)
  wday = aWday - 1
  eom = date.end_of_month
  if eom.wday == wday
    eom
  elsif eom.wday > wday
    (eom.wday - wday).days.ago(eom)
  else
    ((7 - wday) + eom.wday).days.ago(eom)
  end
end
next(date) click to toggle source
# File lib/say_when/cron_expression.rb, line 461
def next(date)
  next_dow = if !is_specified
    date
  elsif is_last
    last = last_wday(date, values.first)
    if last.to_date <= date.to_date
      last = last_wday(1.month.since(date).change(day: 1), values.first)
    end
    last
  elsif nth_day
    nth = nth_wday(nth_day, values.first, date.month, date.year)
    if nth.to_date <= date.to_date
      date = 1.month.since(date)
      nth = nth_wday(nth_day, values.first, date.month, date.year)
    end
    nth
  else
    n = values.detect { |v| v > date.wday }
    n = values[0] if n.blank?
    base = (n < (date.wday + 1)) ? 7 : 0
    days_forward = n + (base - (date.wday + 1))
    days_forward.days.since(date)
  end
  next_dow.change(hour: 0)
end
nth_wday(n, aWday, month, year) click to toggle source

compliments of the ruby way

# File lib/say_when/cron_expression.rb, line 500
def nth_wday(n, aWday, month, year)
  wday = aWday - 1
  if (!n.between? 1,5) or
     (!wday.between? 0,6) or
     (!month.between? 1,12)
    raise ArgumentError
  end
  t = Time.zone.local year, month, 1
  first = t.wday
  if first == wday
    fwd = 1
  elsif first < wday
    fwd = wday - first + 1
  elsif first > wday
    fwd = (wday+7) - first + 1
  end
  target = fwd + (n-1)*7
  begin
    t2 = Time.zone.local year, month, target
  rescue ArgumentError
    return nil
  end
  if t2.mday == target
    t2
  else
    nil
  end
end
parse(exp) click to toggle source
Calls superclass method SayWhen::CronValue#parse
# File lib/say_when/cron_expression.rb, line 409
def parse(exp)
  if self.is_specified = !(expression =~ /\?/)
    if exp =~ /[A-Z]+/
      DAYS.each_with_index { |day, index| exp = exp.gsub(day, (index + 1).to_s) }
    end
    case exp
      when /^L$/ then values << max
      when /^(\d+)L$/ then self.is_last = true; values << $1.to_i
      when /^(\d+)#(\d+)/ then self.values << $1.to_i; self.nth_day = $2.to_i
      else super(exp)
    end
  end
end
to_s() click to toggle source
# File lib/say_when/cron_expression.rb, line 529
def to_s
  "[e:#{expression}, v:#{values.inspect}, is:#{is_specified}, il:#{is_last}, nd:#{nth_day}]\n"
end