Class: SayWhen::DaysOfMonthCronValue

Inherits:
CronValue
  • Object
show all
Defined in:
lib/say_when/cron_expression.rb

Instance Attribute Summary collapse

Attributes inherited from CronValue

#expression, #max, #min, #part, #values

Instance Method Summary collapse

Methods inherited from CronValue

parse_number

Constructor Details

#initialize(exp) ⇒ DaysOfMonthCronValue

Returns a new instance of DaysOfMonthCronValue.



250
251
252
253
254
# File 'lib/say_when/cron_expression.rb', line 250

def initialize(exp)
  self.is_last = false
  self.is_weekday = false
  super(:mday, 1, 31, exp)
end

Instance Attribute Details

#is_lastObject

Returns the value of attribute is_last.



249
250
251
# File 'lib/say_when/cron_expression.rb', line 249

def is_last
  @is_last
end

#is_specifiedObject

Returns the value of attribute is_specified.



249
250
251
# File 'lib/say_when/cron_expression.rb', line 249

def is_specified
  @is_specified
end

#is_weekdayObject

Returns the value of attribute is_weekday.



249
250
251
# File 'lib/say_when/cron_expression.rb', line 249

def is_weekday
  @is_weekday
end

Instance Method Details

#include?(date) ⇒ Boolean

Returns:

  • (Boolean)


333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
# File 'lib/say_when/cron_expression.rb', line 333

def include?(date)
  return true unless is_specified
  last = date.clone
  if is_last
    last = last.end_of_month.to_date
    last = nearest_week_day(last) if is_weekday
    last == date.to_date
  elsif is_weekday
    if values.empty?
      (1..5).include?(date.wday)
    else
      nearest_week_day(date.change(day: values.first)) == date
    end
  else
    super(date)
  end
end

#last(date) ⇒ Object



268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
# File 'lib/say_when/cron_expression.rb', line 268

def last(date)
  result = if !is_specified
    date
  elsif is_last
    eom = date.end_of_month
    eom = nearest_week_day(eom) if is_weekday
    if eom > date
      eom = 1.month.ago(date)
      eom = nearest_week_day(eom.change(day: eom.end_of_month))
    end
    eom
  elsif is_weekday
    if values.empty?
      nearest = nearest_week_day(date)
      if nearest > date
        nearest = 1.month.ago(date)
        nearest = nearest_week_day(date.change(day: date.end_of_month))
      end
    else
      nearest = nearest_week_day(date.change(day: values.first))
      nearest = nearest_week_day(1.month.ago(date).change(day: values.first)) if nearest > date
    end
    nearest
  else
    l = values.reverse.detect { |v| v < date.mday }
    if l.blank?
      1.month.ago(date).change(day: values.last)
    else
      date.change(day: l.to_i)
    end
  end
  result.change(hour: 23, min: 59, sec: 59)
end

#nearest_week_day(date) ⇒ Object



351
352
353
354
355
356
357
358
359
# File 'lib/say_when/cron_expression.rb', line 351

def nearest_week_day(date)
  if (1..5).include?(date.wday)
    date
  elsif date.wday == 6
    (date.beginning_of_month.to_date == date.to_date) ? 2.days.since(date) : 1.day.ago(date)
  elsif date.wday == 0
    (date.end_of_month.to_date == date.to_date) ? date = 2.days.ago(date) : 1.day.since(date)
  end
end

#next(date) ⇒ Object



302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
# File 'lib/say_when/cron_expression.rb', line 302

def next(date)
  result = if !is_specified
    date
  elsif is_last
    last = date.end_of_month
    last = nearest_week_day(last) if is_weekday
    if last < date
      last = 1.month.since(date)
      last = nearest_week_day(last.change(day: last.end_of_month))
    end
    last
  elsif is_weekday
    if values.empty?
      nearest = nearest_week_day(date)
      nearest = nearest_week_day(1.month.since(date).change(day: 1)) if nearest < date
    else
      nearest = nearest_week_day(date.change(day: values.first))
      nearest = nearest_week_day(1.month.since(date).change(day: values.first)) if nearest < date
    end
    nearest
  else
    n = values.detect { |v| v > date.mday }
    if n.blank?
      date.months_since(1).change(day: values.first)
    else
      date.change(day: n.to_i)
    end
  end
  result.change(hour: 0)
end

#parse(exp) ⇒ Object



256
257
258
259
260
261
262
263
264
265
266
# File 'lib/say_when/cron_expression.rb', line 256

def parse(exp)
  if self.is_specified = !(expression =~ /\?/)
    case exp
      when /^(L)$/ then self.is_last = true
      when /^(W)$/ then self.is_weekday = true
      when /^(WL|LW)$/ then self.is_last = (self.is_weekday = true)
      when /^(\d+)W$/ then self.is_weekday = true; self.values << $1.to_i
      else super(exp)
    end
  end
end

#to_sObject



361
362
363
# File 'lib/say_when/cron_expression.rb', line 361

def to_s
  "[e:#{expression}, v:#{values.inspect}, is:#{is_specified}, il:#{is_last}, iw:#{is_weekday}]\n"
end