module Holidays

FIXME This whole file is my next refactor target. We do wayyyyy too much by

convention here. We need hard and fast rules and explicit errors when you
try to parse something that isn't allowed. So if you are a dev recognize
that a lot of the guard statements in here are to codify existing legacy
logic. The fact is that we already require these guards, we just don't
enforce it explicitly. Now we will. And by doing so things will begin
to look very, very messy.

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 various other ‘finder’ contexts 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
PARENT_REGION_LOOKUP
REGIONS
VERSION
WEEKS

Public Class Methods

any_holidays_during_work_week?(date, *options) click to toggle source
# File lib/holidays.rb, line 21
def any_holidays_during_work_week?(date, *options)
  monday = date - (date.wday - 1)
  friday = date + (5 - date.wday)

  holidays = between(monday, friday, *options)

  holidays && holidays.count > 0
end
available_regions() click to toggle source
# File lib/holidays.rb, line 89
def available_regions
  Holidays::REGIONS
end
between(start_date, end_date, *options) click to toggle source
# File lib/holidays.rb, line 34
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)

  raise ArgumentError if end_date < start_date

  if cached_holidays = Factory::Definition.cache_repository.find(start_date, end_date, options)
    return cached_holidays
  end

  Factory::Finder.between.call(start_date, end_date, options)
end
cache_between(start_date, end_date, *options) click to toggle source
# File lib/holidays.rb, line 82
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)

  Factory::Definition.cache_repository.cache_between(start_date, end_date, cache_data, options)
end
load_all() click to toggle source
# File lib/holidays.rb, line 105
def load_all
  path = FULL_DEFINITIONS_PATH + "/"

  Dir.foreach(path) do |item|
    next if item == '.' or item == '..'

    target = path+item
    next if File.extname(target) != '.rb'

    require target
  end
end
load_custom(*files) click to toggle source
# File lib/holidays.rb, line 93
def load_custom(*files)
  regions, rules_by_month, custom_methods, _ = Factory::Definition.file_parser.parse_definition_files(files)

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

  Factory::Definition.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

FIXME All other methods start with a date and require a date. For the next

major version bump we should take the opportunity to change this
signature to match, e.g. next_holidays(from_date, count, options)
# File lib/holidays.rb, line 55
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)

  Factory::Finder.next_holiday.call(holidays_count, from_date, options)
end
on(date, *options) click to toggle source
# File lib/holidays.rb, line 30
def on(date, *options)
  between(date, date, *options)
end
year_holidays(options, from_date = Date.today) click to toggle source

FIXME All other methods start with a date and require a date. For the next

major version bump we should take the opportunity to change this
signature to match, e.g. year_holidays(from_date, options)
# File lib/holidays.rb, line 71
def year_holidays(options, from_date = Date.today)
  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)

  Factory::Finder.year_holiday.call(from_date, options)
end

Private Class Methods

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