Holidays can be defined as belonging to one or more regions and sub regions. The Holidays#on, Holidays#between, Date#holidays and Date#holiday? methods each allow you to specify a specific region.
There are several different ways that you can specify a region:
By region. For example, return holidays in the Canada with :ca.
By region and sub regions. For example, return holidays in Germany and all its sub regions with :de_.
By sub region. Return national holidays in Spain plus holidays in Spain's Valencia region with :es_v.
Any region. Return holidays from any loaded region.
You can load all the available holiday definition sets by running
Holidays.load_all
Return holidays on the day they are observed (e.g. on a Monday if they fall on a Sunday).
Include informal holidays (e.g. Valentine's Day)
Return all holidays in the :ca and :us regions on the day that they are observed.
Holidays.between(from, to, :ca, :us, :observed)
Return all holidays in :ca and any :ca sub-region.
Holidays.between(from, to, :ca_)
Return all holidays in :ca_bc sub-region (which includes the :ca), including informal holidays.
Holidays.between(from, to, :ca_bc, :informal)
Returns an array of symbols all the available holiday definitions.
Optional `full_path` param is used internally for loading all the definitions.
# File lib/holidays.rb, line 296 def self.available(full_path = false) paths = Dir.glob(DEFINITION_PATH + '/*.rb') full_path ? paths : paths.collect { |path| path.match(/([a-z_-]+)\.rb/)[1].to_sym } end
Get all holidays occuring between two dates, inclusively.
Returns an array of hashes or nil.
Each holiday is returned as a hash with the following fields:
Ruby Date object.
Ruby Date object.
One or more region symbols, :informal and/or :observed.
from = Date.civil(2008,7,1) to = Date.civil(2008,7,31) Holidays.between(from, to, :ca, :us) => [{:name => 'Canada Day', :regions => [:ca]...} {:name => 'Independence Day'', :regions => [:us], ...}]
# File lib/holidays.rb, line 105 def self.between(start_date, end_date, *options) # remove the timezone 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) # get simple dates 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| # Always include month '0' for variable-month holidays dates[date.year] = [0] unless dates[date.year] # TODO: test this, maybe should push then flatten 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]) # Skip informal holidays unless they have been requested next if h[:type] == :informal and not informal if h[:function] # Holiday definition requires a calculation result = call_proc(h[:function], year) # Procs may return either Date or an integer representing mday if result.kind_of?(Date) month = result.month mday = result.mday else mday = result end else # Calculate the mday mday = h[:mday] || Date.calculate_mday(year, month, h[:week], h[:wday]) end # Silently skip bad mdays begin date = Date.civil(year, month, mday) rescue; next; end # If the :observed option is set, calculate the date when the holiday # is observed. 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
Monday on or before May 24
# File lib/holidays/ca.rb, line 58 def self.ca_victoria_day(year) date = Date.civil(year,5,24) if date.wday > 1 date -= (date.wday - 1) elsif date.wday == 0 date -= 6 end date end
# File lib/holidays/nz.rb, line 48 def self.closest_monday(date) if [1, 2, 3, 4].include?(date.wday) date -= (date.wday - 1) elsif 0 == date.wday date += 1 else date += 8 - date.wday end date end
Germany: Wednesday before November 23
# File lib/holidays/de.rb, line 40 def self.de_buss_und_bettag(year) date = Date.civil(year,11,23) if date.wday > 3 date -= (date.wday - 3) else date -= (date.wday + 4) end date end
Get the date of Easter Sunday in a given year. From Easter Sunday, it is possible to calculate many traditional holidays in Western countries. Returns a Date object.
# File lib/holidays.rb, line 216 def self.easter(year) y = year a = y % 19 b = y / 100 c = y % 100 d = b / 4 e = b % 4 f = (b + 8) / 25 g = (b - f + 1) / 3 h = (19 * a + b - d - g + 15) % 30 i = c / 4 k = c % 4 l = (32 + 2 * e + 2 * i - h - k) % 7 m = (a + 11 * h + 22 * l) / 451 month = (h + l - 7 * m + 114) / 31 day = ((h + l - 7 * m + 114) % 31) + 1 Date.civil(year, month, day) end
Finland: Mid-summer (Saturday between June 20–26)
# File lib/holidays/scandinavia.rb, line 139 def self.fi_juhannuspaiva(year) date = Date.civil(year,6,20) date += (6 - date.wday) date end
Finland: All Saint's Day (Saturday between Oct 31 and Nov 6)
# File lib/holidays/scandinavia.rb, line 147 def self.fi_pyhainpaiva(year) date = Date.civil(year,10,31) date += (6 - date.wday) date end
Does the given work-week have any holidays?
A Date object.
One or more region symbols, and/or :informal. Automatically includes :observed. If you don't want this, pass :no_observed
The given Date can be any day of the week. Returns true if any holidays fall on Monday - Friday of the given week.
# File lib/holidays.rb, line 79 def self.full_week?(date, *options) days_to_monday = date.wday - 1 days_to_friday = 5 - date.wday start_date = date - days_to_monday end_date = date + days_to_friday options += [:observed] unless options.include?(:no_observed) options.delete(:no_observed) self.between(start_date, end_date, options).empty? end
Iceland: first day of summer (Thursday after 18 April)
# File lib/holidays/scandinavia.rb, line 111 def self.is_sumardagurinn_fyrsti(year) date = Date.civil(year,4,18) if date.wday < 4 date += (4 - date.wday) else date date += (11 - date.wday) end date end
# File lib/holidays/jp.rb, line 92 def self.jp_citizons_holiday(year) year < 2003 and return nil ncd = Holidays.jp_national_culture_day(year) if ncd.wday == 3 ncd - 1 else nil end end
# File lib/holidays/jp.rb, line 72 def self.jp_national_culture_day(year) day = case year when 1851..1899 22.2588 when 1900..1979 23.2588 when 1980..2099 23.2488 when 2100..2150 24.2488 else raise IndexError.new("Out of range") end day += 0.242194 * (year - 1980) - ((year - 1980)/4).floor day = day.floor Date.civil(year, 9, day) end
# File lib/holidays/jp.rb, line 103 def self.jp_substitute_holiday(*date) date = date[0].kind_of?(Date) ? date.first : Date.civil(*date) date.wday == 0 ? date+1 : nil end
# File lib/holidays/jp.rb, line 52 def self.jp_vernal_equinox_day(year) day = case year when 1851..1899 19.8277 when 1900..1979 20.8357 when 1980..2099 20.8431 when 2100..2150 21.8510 else raise IndexError.new("Out of range") end day += 0.242194 * (year - 1980) - ((year - 1980)/4).floor day = day.floor Date.civil(year, 3, day) end
Load all available holiday definitions
# File lib/holidays.rb, line 302 def self.load_all self.available(true).each { |path| require path } end
# File lib/holidays/nz.rb, line 65 def self.next_week(date) date + 7 end
Get all holidays on a given date.
A Date object.
One or more region symbols, :informal and/or :observed.
Returns an array of hashes or nil. See Holidays#between for the output format.
Also available via Date#holidays.
# File lib/holidays.rb, line 68 def self.on(date, *options) self.between(date, date, options) end
A method to calculate the orthodox easter date, returns date in the Gregorian (western) calendar Safe until appr. 4100 AD, when one leap day will be removed. Returns a Date object.
# File lib/holidays.rb, line 238 def self.orthodox_easter(year) y = year g = y % 19 i = (19 * g + 15) % 30 j = (year + year/4 + i) % 7 j_month = 3 + (i - j + 40) / 44 j_day = i - j + 28 - 31 * (j_month / 4) j_date = Date.civil(year, j_month, j_day) case # up until 1582, julian and gregorian easter dates were identical when year <= 1582 offset = 0 # between the years 1583 and 1699 10 days are added to the julian day count when (year >= 1583 and year <= 1699) offset = 10 # after 1700, 1 day is added for each century, except if the century year is exactly divisible by 400 (in which case no days are added). # Safe until 4100 AD, when one leap day will be removed. when year >= 1700 offset = (year - 1700).divmod(100)[0] + ((year - year.divmod(100)[1]).divmod(400)[1] == 0 ? 0 : 1) - (year - year.divmod(100)[1] - 1700).divmod(400)[0] + 10 end # add offset to the julian day return Date.jd(j_date.jd + offset) end
Poland: January 6 is holiday since 2011
# File lib/holidays/pl.rb, line 65 def self.pl_trzech_kroli(year) year >= 2011 ? 6 : nil end
Poland: January 6 wasn't holiday before 2011
# File lib/holidays/pl.rb, line 71 def self.pl_trzech_kroli_informal(year) year < 2011 ? 6 : nil end
# File lib/holidays/nz.rb, line 60 def self.previous_friday(date) date - 3 end
Sweden: All Saint's Day (Saturday between Oct 31 and Nov 6)
# File lib/holidays/scandinavia.rb, line 131 def self.se_alla_helgons_dag(year) date = Date.civil(year,10,31) date += (6 - date.wday) date end
Sweden: Mid-summer (Saturday between June 20–26)
# File lib/holidays/scandinavia.rb, line 123 def self.se_midsommardagen(year) date = Date.civil(year,6,20) date += (6 - date.wday) date end
Move date to Monday if it occurs on a Sunday. Used as a callback function.
# File lib/holidays.rb, line 264 def self.to_monday_if_sunday(date) date += 1 if date.wday == 0 date end
Move date to Monday if it occurs on a Saturday on Sunday. Used as a callback function.
# File lib/holidays.rb, line 271 def self.to_monday_if_weekend(date) date += 1 if date.wday == 0 date += 2 if date.wday == 6 date end
Move Boxing Day if it falls on a weekend, leaving room for Christmas. Used as a callback function.
# File lib/holidays.rb, line 279 def self.to_weekday_if_boxing_weekend(date) date += 2 if date.wday == 6 or date.wday == 0 date end
Move date to Monday if it occurs on a Sunday or to Friday if it occurs on a Saturday. Used as a callback function.
# File lib/holidays.rb, line 287 def self.to_weekday_if_weekend(date) date += 1 if date.wday == 0 date -= 1 if date.wday == 6 date end
Generated with the Darkfish Rdoc Generator 2.