Module Holidays
In: lib/holidays.rb

Region options

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:

:region
By region. For example, return holidays in the Canada with :ca.
:region_
By region and sub regions. For example, return holidays in Germany and all its sub regions with :de_.
:region_sub
By sub region. Return national holidays in Spain plus holidays in Spain‘s Valencia region with :es_v.
:any
Any region. Return holidays from any loaded region.

Other options

:observed
Return holidays on the day they are observed (e.g. on a Monday if they fall on a Sunday).
:informal
Include informal holidays (e.g. Valentine‘s Day)

Examples

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)

Methods

Classes and Modules

Class Holidays::UnkownRegionError

Constants

VERSION = '0.9.0'
WEEKS = {:first => 1, :second => 2, :third => 3, :fourth => 4, :fifth => 5, :last => -1}
MONTH_LENGTHS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
DAY_SYMBOLS = Date::DAYNAMES.collect { |n| n.downcase.intern }

Public Class methods

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:

start_date
Ruby Date object.
end_date
Ruby Date object.
options
One or more region symbols, :informal and/or :observed.

Example

  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], ...}]

[Source]

     # File lib/holidays.rb, line 84
 84:   def self.between(start_date, end_date, *options)
 85:     regions, observed, informal = parse_options(options)
 86:     holidays = []
 87: 
 88:     dates = {}
 89:     (start_date..end_date).each do |date|
 90:       # Always include month '0' for variable-month holidays
 91:       dates[date.year] = [0] unless dates[date.year]      
 92:       # TODO: test this, maybe should push then flatten
 93:       dates[date.year] << date.month unless dates[date.year].include?(date.month)
 94:     end
 95: 
 96:     dates.each do |year, months|
 97:       months.each do |month|
 98:         next unless hbm = @@holidays_by_month[month]
 99: 
100:         hbm.each do |h|
101:           next unless in_region?(regions, h[:regions])
102:           
103:           # Skip informal holidays unless they have been requested
104:           next if h[:type] == :informal and not informal
105:           
106:           if h[:function]
107:             # Holiday definition requires a calculation
108:             result = call_proc(h[:function], year)
109:             
110:             # Procs may return either Date or an integer representing mday
111:             if result.kind_of?(Date)
112:               month = result.month
113:               mday = result.mday
114:             else
115:               mday = result
116:             end
117:           else
118:             # Calculate the mday
119:             mday = h[:mday] || Date.calculate_mday(year, month, h[:week], h[:wday])
120:           end
121: 
122:           # Silently skip bad mdays
123:           begin
124:             date = Date.civil(year, month, mday)
125:           rescue; next; end
126: 
127:           # If the :observed option is set, calculate the date when the holiday
128:           # is observed.
129:           if observed and h[:observed]
130:             date = call_proc(h[:observed], date)
131:           end
132: 
133:           if date.between?(start_date, end_date)
134:             holidays << {:date => date, :name => h[:name], :regions => h[:regions]}
135:           end
136: 
137:         end
138:       end
139:     end
140: 
141:     holidays
142:   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.

[Source]

     # File lib/holidays.rb, line 178
178:   def self.easter(year)
179:     y = year
180:     a = y % 19
181:     b = y / 100
182:     c = y % 100
183:     d = b / 4
184:     e = b % 4
185:     f = (b + 8) / 25
186:     g = (b - f + 1) / 3
187:     h = (19 * a + b - d - g + 15) % 30
188:     i = c / 4
189:     k = c % 4
190:     l = (32 + 2 * e + 2 * i - h - k) % 7
191:     m = (a + 11 * h + 22 * l) / 451
192:     month = (h + l - 7 * m + 114) / 31
193:     day = ((h + l - 7 * m + 114) % 31) + 1
194:     Date.civil(year, month, day)
195:   end

Get all holidays on a given date.

date
A Date object.
:options
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.

[Source]

    # File lib/holidays.rb, line 64
64:   def self.on(date, *options)
65:     self.between(date, date, options)
66:   end

Move date to Monday if it occurs on a Sunday. Used as a callback function.

[Source]

     # File lib/holidays.rb, line 199
199:   def self.to_monday_if_sunday(date)
200:     date += 1 if date.wday == 0
201:     date
202:   end

Move date to Monday if it occurs on a Saturday on Sunday. Used as a callback function.

[Source]

     # File lib/holidays.rb, line 206
206:   def self.to_monday_if_weekend(date)
207:     date += 1 if date.wday == 0
208:     date += 2 if date.wday == 6
209:     date
210:   end

Move Boxing Day if it falls on a weekend, leaving room for Christmas. Used as a callback function.

[Source]

     # File lib/holidays.rb, line 214
214:   def self.to_weekday_if_boxing_weekend(date)
215:     date += 2 if date.wday == 6 or date.wday == 0
216:     date
217:   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.

[Source]

     # File lib/holidays.rb, line 222
222:   def self.to_weekday_if_weekend(date)
223:     date += 1 if date.wday == 0
224:     date -= 1 if date.wday == 6
225:     date
226:   end

[Validate]