module Holidays

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.

You can load all the available holiday definition sets by running

Holidays.load_all

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)

This context builds a hash that contains {:year => [<array of months>]}. The idea is that we will iterate over each year and then over each month internally and check to see if the supplied dates match any holidays for the region and date. So if we supply start_date of 2015/1/1 and end_date of 2015/6/1 then we will return a date driver of {:2015 => [0, 1, 2, 5, 6, 7]}. In the logic in the 'between' use case we will iterate over this and compare dates in these months to the supplied range to determine whether they should be returned to the user.

Constants

DAY_SYMBOLS
DEFINITIONS_PATH
FULL_DEFINITIONS_PATH
MONTH_LENGTHS
REGIONS
VERSION
WEEKS

Public Class Methods

any_holidays_during_work_week?(date, *options) click to toggle source

Does the given work-week have any holidays?

date

A Date object.

:options

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 any_holidays_during_work_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)
  between(start_date, end_date, options).empty?
end
available_regions() click to toggle source

Returns an array of symbols of all the available holiday regions.

# File lib/holidays.rb, line 167
def available_regions
  Holidays::REGIONS
end
between(start_date, end_date, *options) click to toggle source

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], ...}]
# File lib/holidays.rb, line 105
def between(start_date, end_date, *options)
  raise ArgumentError unless start_date && end_date

  # 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)

  start_date, end_date = get_date(start_date), get_date(end_date)

  if cached_holidays = definition_cache_repository.find(start_date, end_date, options)
    return cached_holidays
  end

  regions, observed, informal = OptionFactory.parse_options.call(options)
  date_driver_hash = UseCaseFactory.dates_driver_builder.call(start_date, end_date)

  UseCaseFactory.between.call(start_date, end_date, date_driver_hash, regions, observed, informal)
end
cache_between(start_date, end_date, *options) click to toggle source

Allows a developer to explicitly calculate and cache holidays within a given period

# File lib/holidays.rb, line 159
def cache_between(start_date, end_date, *options)
  start_date, end_date = get_date(start_date), get_date(end_date)
  cache_data = between(start_date, end_date, *options)

  definition_cache_repository.cache_between(start_date, end_date, cache_data, options)
end
load_custom(*files) click to toggle source

Parses provided holiday definition file(s) and loads them so that they are immediately available.

# File lib/holidays.rb, line 172
def load_custom(*files)
  regions, rules_by_month, custom_methods, tests = DefinitionFactory.file_parser.parse_definition_files(files)

  custom_methods.each do |method_key, method_entity|
    custom_methods[method_key] = Holidays::DefinitionFactory.custom_method_proc_decorator.call(method_entity)
  end

  DefinitionFactory.merger.call(regions, rules_by_month, custom_methods)

  rules_by_month
end
next_holidays(holidays_count, options, from_date = Date.today) click to toggle source

Get next holidays occuring from date, inclusively.

Returns an array of hashes or nil.

Incoming arguments are below:

holidays_count

Ruby Numeric object. This is the number of holidays to return

options

One or more region symbols, :informal and/or :observed.

from_date

Ruby Date object. This is an optional param, defaulted today.

Example

Date.today
=> Tue, 23 Feb 2016

regions = [:us, :informal]

Holidays.next_holidays(3, regions)
=> [{:name => "St. Patrick's Day",...},
    {:name => "Good Friday",...},
    {:name => "Easter Sunday",...}]
# File lib/holidays.rb, line 143
def next_holidays(holidays_count, options, from_date = Date.today)
  raise ArgumentError unless holidays_count
  raise ArgumentError if options.empty?
  raise ArgumentError unless options.is_a?(Array)

  # remove the timezone
  from_date = from_date.new_offset(0) + from_date.offset if from_date.respond_to?(:new_offset)

  from_date = get_date(from_date)
  regions, observed, informal = OptionFactory.parse_options.call(options)
  date_driver_hash = UseCaseFactory.dates_driver_builder.build(from_date)

  UseCaseFactory.next_holiday.call(holidays_count, from_date, date_driver_hash, regions, observed, informal)
end
on(date, *options) click to toggle source

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.

# File lib/holidays.rb, line 68
def on(date, *options)
  between(date, date, options)
end

Private Class Methods

definition_cache_repository() click to toggle source
# File lib/holidays.rb, line 194
def definition_cache_repository
  DefinitionFactory.cache_repository
end
get_date(date) click to toggle source
# File lib/holidays.rb, line 186
def get_date(date)
  if date.respond_to?(:to_date)
    date.to_date
  else
    Date.civil(date.year, date.mon, date.mday)
  end
end