Class: Holidays::DateCalculator::DayOfMonth

Inherits:
Object
  • Object
show all
Defined in:
lib/holidays/date_calculator/day_of_month.rb

Overview

Calculate day of the month based on the week number and the day of the week.

Parameters

year

Integer.

month

Integer from 1-12.

week

One of :first, :second, :third, :fourth, :fifth or :last.

wday

Day of the week as an integer from 0 (Sunday) to 6 (Saturday) or as a symbol (e.g. :monday).

Returns an integer.

Examples

First Monday of January, 2008:

Holidays::Factory::DateCalculator.day_of_month_calculator.call(2008, 1, :first, :monday)
=> 7

Third Thursday of December, 2008:

Holidays::Factory::DateCalculator.day_of_month_calculator.call(2008, 12, :third, :thursday)
=> 18

Last Monday of January, 2008:

Holidays::Factory::DateCalculator.day_of_month_calculator.call(2008, 1, :last, 1)
=> 28

– see www.irt.org/articles/js050/index.htm

Instance Method Summary collapse

Instance Method Details

#call(year, month, week, wday) ⇒ Object

Raises:

  • (ArgumentError)


31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
# File 'lib/holidays/date_calculator/day_of_month.rb', line 31

def call(year, month, week, wday)
  raise ArgumentError, "Week parameter must be one of Holidays::WEEKS (provided #{week})." unless weeks.include?(week) or weeks.has_value?(week)

  unless wday.kind_of?(Numeric) and wday.between?(0,6) or day_symbols.index(wday)
    raise ArgumentError, "Wday parameter must be an integer between 0 and 6 or one of Holidays::DAY_SYMBOLS."
  end

  week = weeks[week] if week.kind_of?(Symbol)
  wday = day_symbols.index(wday) if wday.kind_of?(Symbol)

  # :first, :second, :third, :fourth or :fifth
  if week > 0
    return ((week - 1) * 7) + 1 + ((wday - Date.civil(year, month,(week-1)*7 + 1).wday) % 7)
  end

  days = month_lengths[month-1]

  days = 29 if month == 2 and Date.leap?(year)

  return days - ((Date.civil(year, month, days).wday - wday + 7) % 7) - (7 * (week.abs - 1))
end