class TZInfo::TZDataDayOfMonth
:nodoc:
@private
result in a day in the neighbouring month.
a last week day or a week day >= or <= than a specific day of month. Can
A tz data day of the month reference. Can either be an absolute day,
def initialize(spec)
def initialize(spec) raise "Invalid on: #{spec}" if spec !~ /^([0-9]+)|(last([A-z]+))|(([A-z]+)([<>]=)([0-9]+))$/ if $1 @type = :absolute @day_of_month = $1.to_i elsif $3 @type = :last @day_of_week = parse_day_of_week($3) else @type = :comparison @day_of_week = parse_day_of_week($5) @operator = parse_operator($6) @day_of_month = $7.to_i end end
def parse_day_of_week(day_of_week)
def parse_day_of_week(day_of_week) lower = day_of_week.downcase if lower =~ /^mon/ 1 elsif lower =~ /^tue/ 2 elsif lower =~ /^wed/ 3 elsif lower =~ /^thu/ 4 elsif lower =~ /^fri/ 5 elsif lower =~ /^sat/ 6 elsif lower =~ /^sun/ 0 else raise "Invalid day of week: #{day_of_week}" end end
def parse_operator(operator)
def parse_operator(operator) if operator == '>=' :greater_equal elsif operator == '<=' :less_equal else raise "Invalid operator: #{operator}" end end
def to_absolute(year, month)
def to_absolute(year, month) case @type when :last last_day_in_month = (Date.new(year, month, 1) >> 1) - 1 offset = last_day_in_month.wday - @day_of_week offset = offset + 7 if offset < 0 last_day_in_month - offset when :comparison pivot = Date.new(year, month, @day_of_month) offset = @day_of_week - pivot.wday offset = -offset if @operator == :less_equal offset = offset + 7 if offset < 0 offset = -offset if @operator == :less_equal pivot + offset else #absolute Date.new(year, month, @day_of_month) end end