def self.between(start_date, end_date, *options)
start_date = start_date.new_offset(0) + start_date.offset if start_date.respond_to?(:new_offset)
end_date = end_date.new_offset(0) + end_date.offset if end_date.respond_to?(:new_offset)
if start_date.respond_to?(:to_date)
start_date = start_date.to_date
else
start_date = Date.civil(start_date.year, start_date.mon, start_date.mday)
end
if end_date.respond_to?(:to_date)
end_date = end_date.to_date
else
end_date = Date.civil(end_date.year, end_date.mon, end_date.mday)
end
regions, observed, informal = parse_options(options)
holidays = []
dates = {}
(start_date..end_date).each do |date|
dates[date.year] = [0] unless dates[date.year]
dates[date.year] << date.month unless dates[date.year].include?(date.month)
end
dates.each do |year, months|
months.each do |month|
next unless hbm = @@holidays_by_month[month]
hbm.each do |h|
next unless in_region?(regions, h[:regions])
next if h[:type] == :informal and not informal
if h[:function]
result = call_proc(h[:function], year)
if result.kind_of?(Date)
month = result.month
mday = result.mday
else
mday = result
end
else
mday = h[:mday] || Date.calculate_mday(year, month, h[:week], h[:wday])
end
begin
date = Date.civil(year, month, mday)
rescue; next; end
if observed and h[:observed]
date = call_proc(h[:observed], date)
end
if date.between?(start_date, end_date)
holidays << {:date => date, :name => h[:name], :regions => h[:regions]}
end
end
end
end
holidays.sort{|a, b| a[:date] <=> b[:date] }
end