Coder Social home page Coder Social logo

holidays's Introduction

Ruby Holidays Gem Build Status

Functionality to deal with holidays in Ruby.

Extends Ruby's built-in Date and Time classes and supports custom holiday definition lists.

Installation

gem install holidays

Tested versions

This gem is tested with the following ruby versions:

  • 2.4.5
  • 2.5.3
  • 2.6.1
  • 2.7.7
  • 3.0.6
  • 3.1.4
  • 3.2.2
  • 3.3.0
  • JRuby 9.2.21.0
  • JRuby 9.4.2.0

Semver

This gem follows semantic versioning. The guarantee specifically covers:

  • methods in the top-most Holidays namespace e.g. Holidays.<method>
  • the core extensions

Please note that we consider definition changes to be 'minor' bumps, meaning they are backwards compatible with your code but might give different holiday results!

Time zones

Time zones are ignored. This library assumes that all dates are within the same time zone.

Usage

This gem offers multiple ways to check for holidays for a variety of scenarios.

Checking a specific date

Get all holidays on April 25, 2008 in Australia:

Holidays.on(Date.new(2008, 4, 25), :au)
=> [{:name => 'ANZAC Day',...}]

You can check multiple regions in a single call:

Holidays.on(Date.new(2008, 1, 1), :us, :fr)
=> [{:name=>"New Year's Day", :regions=>[:us],...},
    {:name=>"Jour de l'an", :regions=>[:fr],...}]

You can leave off 'regions' to get holidays for any region in our definitions:

 Holidays.on(Date.new(2007, 4, 25))
=> [{:name=>"ANZAC Day", :regions=>[:au],...},
    {:name=>"Festa della Liberazione", :regions=>[:it],...},
    {:name=>"Dia da Liberdade", :regions=>[:pt],...}
    ...
   ]

Checking a date range

Get all holidays during the month of July 2008 in Canada and the US:

from = Date.new(2008,7,1)
to = Date.new(2008,7,31)

Holidays.between(from, to, :ca, :us)
=> [{:name => 'Canada Day',...}
    {:name => 'Independence Day',...}]

Check for 'informal' holidays

You can pass the 'informal' flag to include holidays specified as informal in your results. See here for information on what constitutes 'informal' vs 'formal'.

By default this flag is turned off, meaning no informal holidays will be returned.

Get Valentine's Day in the US:

Holidays.on(Date.new(2018, 2, 14), :us, :informal)
=> [{:name=>"Valentine's Day",...}]

Leaving off 'informal' will mean that Valentine's Day is not returned:

Holidays.on(Date.new(2018, 2, 14), :us)
=> []

Get informal holidays during the month of February 2008 for any region:

from = Date.new(2008,2,1)
to = Date.new(2008,2,15)

Holidays.between(from, to, :informal)
=> [{:name => 'Valentine\'s Day',...}]

Check for 'observed' holidays

You can pass the 'observed' flag to include holidays that are observed on different days than they actually occur. See here for further explanation of 'observed'.

By default this flag is turned off, meaning no observed logic will be applied.

Get holidays that are observed on Monday July 2, 2007 in British Columbia, Canada:

Holidays.on(Date.new(2007, 7, 2), :ca_bc, :observed)
=> [{:name => 'Canada Day',...}]

Leaving off the 'observed' flag will mean that 'Canada Day' is not returned since it actually falls on Sunday July 1:

Holidays.on(Date.new(2007, 7, 2), :ca_bc)
=> []

Holidays.on(Date.new(2007, 7, 1), :ca_bc)
=> [{:name=>"Canada Day", :regions=>[:ca],...}]

Get all observed US Federal holidays between 2018 and 2019:

from = Date.new(2018,1,1)
to = Date.new(2019,12,31)

Holidays.between(from, to, :federalreserve, :observed)
=> [{:name => "New Year's Day"....}
    {:name => "Birthday of Martin Luther King, Jr"....}]

Check whether any holidays occur during work week

Check if there are any holidays taking place during a specified work week. 'Work week' is defined as the period of Monday through Friday of the week specified by the date.

Check whether a holiday falls during first week of the year for any region:

Holidays.any_holidays_during_work_week?(Date.new(2016, 1, 1))
=> true

You can also pass in informal or observed:

# Returns true since Valentine's Day falls on a Wednesday
Holidays.any_holidays_during_work_week?(Date.new(2018, 2, 14), :us, :informal)
=> true

# Returns false if you don't specify informal
Holidays.any_holidays_during_work_week?(Date.new(2018, 2, 14), :us)
=> false

# Returns true since Veteran's Day is observed on Monday November 12, 2018
Holidays.any_holidays_during_work_week?(Date.new(2018, 11, 12), :us, :observed)
=> true

# Returns false if you don't specify observed since the actual holiday is on Sunday November 11th 2018
Holidays.any_holidays_during_work_week?(Date.new(2018, 11, 12), :us)
=> false

Find the next holiday(s) that will occur from a specific date

Get the next holidays occurring from February 23, 2016 for the US:

Holidays.next_holidays(3, [:us, :informal], Date.new(2016, 2, 23))
=> [{:name => "St. Patrick's Day",...}, {:name => "Good Friday",...}, {:name => "Easter Sunday",...}]

You can specify the number of holidays to return. This method will default to Date.today if no date is provided.

Find all holidays occurring starting from a specific date to the end of the year

Get all holidays starting from February 23, 2016 to end of year in the US:

Holidays.year_holidays([:ca_on], Date.new(2016, 2, 23))
=> [{:name=>"Good Friday",...},
    {:name=>"Easter Sunday",...},
    {:name=>"Victoria Day",...},
    {:name=>"Canada Day",...},
    {:name=>"Civic Holiday",...},
    {:name=>"Labour Day",...},
    {:name=>"Thanksgiving",...},
    {:name=>"Remembrance Day",...},
    {:name=>"Christmas Day",...},
    {:name=>"Boxing Day",...}]

This method will default to Date.today if no date is provided.

Return all available regions

Return all available regions:

Holidays.available_regions
=> [:ar, :at, ..., :sg] # this will be a big array

Loading Custom Definitions on the fly

In addition to the provided definitions you can load custom definitions file on the fly and use them immediately.

To load custom 'Company Founding' holiday on June 1st:

Holidays.load_custom('/home/user/holiday_definitions/custom_holidays.yaml')
Holidays.on(Date.new(2013, 6, 1), :my_custom_region)
=> [{:name => 'Company Founding',...}]

Custom definition files must match the syntax of the existing definition files.

Multiple files can be loaded at the same time:

Holidays.load_custom(
  '/home/user/holidays/custom_holidays1.yaml',
  '/home/user/holidays/custom_holidays2.yaml'
)

Extending Ruby's Date and Time classes

Date

To extend the 'Date' class:

require 'holidays/core_extensions/date'

class Date
  include Holidays::CoreExtensions::Date
end

Now you can check which holidays occur in Iceland on January 1, 2008:

d = Date.new(2008,7,1)

d.holidays(:is)
=> [{:name => 'Nýársdagur'}...]

Or lookup Canada Day in different regions:

d = Date.new(2008,7,1)

d.holiday?(:ca) # Canada
=> true

d.holiday?(:ca_bc) # British Columbia, Canada
=> true

d.holiday?(:fr) # France
=> false

Or return the new date based on the options:

d = Date.new(2008,7,1)
d.change(:year => 2016, :month => 1, :day => 1)
=> #<Date: 2016-01-01 ((2457389j,0s,0n),+0s,2299161j)>

Or you can calculate the day of the month:

Date.calculate_mday(2015, 4, :first, 2)
=> 7

Time

require 'holidays/core_extensions/time'

class Time
  include Holidays::CoreExtensions::Time
end

Find end of month for given date:

d = Date.new(2016,8,1)
d.end_of_month
=> #<Date: 2016-08-31 ((2457632j,0s,0n),+0s,2299161j)>

Caching Holiday Lookups

If you are checking holidays regularly you can cache your results for improved performance. Run this before looking up a holiday (e.g. in an initializer):

YEAR = 365 * 24 * 60 * 60
Holidays.cache_between(Time.now, Time.now + 2 * YEAR, :ca, :us, :observed)

Holidays for the regions specified within the dates specified will be pre-calculated and stored in-memory. Future lookups will be much faster.

How to contribute

See our contribution guidelines for information on how to help out!

Credits and code

Plus all of these wonderful contributors!

holidays's People

Contributors

adamstrickland avatar alexdunae avatar brunas avatar causztic avatar dceddia avatar dgrambow avatar dunyakirkali avatar ghiculescu avatar guizmaii avatar hahahana avatar jak78 avatar jonathanpike avatar knut2 avatar marcelo-soto avatar marcoroth avatar matekb avatar mathijsk93 avatar mipereira avatar mirelon avatar morrme avatar mzruya avatar paulrbr avatar ppeble avatar rojoko avatar ryosukeyamazaki avatar scambra avatar sebastianedwards avatar sirkosi avatar ttwo32 avatar y-yagi avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

holidays's Issues

Require Ruby 2.0 and up only

Since Ruby 1.9.3 is no longer supported we should require the newer versions. This shouldn't (I hope) require code changes, simply a change in what we test on Travis.

Add valid year feature to holidays

Holidays can be revoked, created, and changed so there should be functionality that specifies the validity of a holiday in certain years. For example, Memorial Day prior to 1971 had a different definition: instead of always falling on May 30 it was changed to the last Monday in May. We need functionality that can select the correct holidays based on the year. So if we are searching for holidays that fall between 1970 and 1971, we should have logic that filters out the holiday definition based on date.

Perhaps something like:
5:

  • name: Memorial Day
    week: -1
    wday: 1
    regions: [federal_reserve]
    valid: <= 1970
  • name: Decoration Memorial Day
    mday: 30
    regions: [federal_reserve]
    valid: >= 1971

Issue with Day after Thanksgiving

Day after Thanksgiving does not always get calculated to the date following Thanksgiving. If the first day of the month falls on a Friday the the current calculation of the 4th Friday doesn't work and ends up being the week before Thanksgiving. It really should be calculated as the 4th Thursday + 1 day

> Holidays.between(Date.new(2013, 11, 01), Date.new(2013, 11, 30), :us_ca, :us, :informal)
=> [{:date=>Mon, 11 Nov 2013, :name=>"Veterans Day", :regions=>[:us]}, {:date=>Fri, 22 Nov 2013, :name=>"Day after Thanksgiving", :regions=>[:us_ca]}, {:date=>Thu, 28 Nov 2013, :name=>"Thanksgiving", :regions=>[:us]}]

UnknownRegionError fires incorrectly for non north-american regions

I run into the following problem.
The first time when I use a region outside of north-america (eg. :de , :no, :el) in a Holidays Method (Holidays.on, Holidays.between) I get a UnknownRegionError, but firing the command a second time Holidays returns the
right value.

ruby-1.9.2-p290 :017 > g = Holidays.on('2011-1-1'.to_date, :el)
Holidays::UnknownRegionError: Holidays::UnknownRegionError
from /home/roland/.rvm/gems/ruby-1.9.2-p290@rails3tutorial/gems/holidays-1.0.3/lib/holidays.rb:308:in parse_regions' from /home/roland/.rvm/gems/ruby-1.9.2-p290@rails3tutorial/gems/holidays-1.0.3/lib/holidays.rb:279:inparse_options'
from /home/roland/.rvm/gems/ruby-1.9.2-p290@rails3tutorial/gems/holidays-1.0.3/lib/holidays.rb:103:in between' from /home/roland/.rvm/gems/ruby-1.9.2-p290@rails3tutorial/gems/holidays-1.0.3/lib/holidays.rb:66:inon'
from (irb):17
from /home/roland/.rvm/gems/ruby-1.9.2-p290@rails3tutorial/gems/railties-3.0.9/lib/rails/commands/console.rb:44:in start' from /home/roland/.rvm/gems/ruby-1.9.2-p290@rails3tutorial/gems/railties-3.0.9/lib/rails/commands/console.rb:8:instart'
from /home/roland/.rvm/gems/ruby-1.9.2-p290@rails3tutorial/gems/railties-3.0.9/lib/rails/commands.rb:23:in <top (required)>' from script/rails:6:inrequire'
from script/rails:6:in `

'

ruby-1.9.2-p290 :018 > g = Holidays.on('2011-1-1'.to_date, :el)
=> [{:date=>Sat, 01 Jan 2011, :name=>"Πρωτοχρονιά", :regions=>[:el]}]

Hijri-Calendar

I'm trying to implement the Islamic holidays too, but when I create a yaml-file, for "islam", and then the rb-file, I get the error, that it can't be loaded. Why? Any Ideas?

Observed holidays that span month-end are not found

While researching #141 I found that it seems as if observed holidays that fall across month boundaries are not found as expected.

An example: Holidays.on(Date.civil(2017, 1, 30), :nz_ne, :observed)

  • region: nz_ne - Nelson Anniversary Day - actual holiday is 2/1 but it is observed on the closest monday. For 2017 2/1 is a Wednesday, meaning that it is actually observed on 1/30/2017. When we submit the above we should see the 'Nelson Anniversary Day', since Monday, 1/30/2017 is when it is observed.

The reason that I see is that when we build the dates hash here we do it based on the specified month. In the case above it will return {2017 => [0, 1]} since we gave 1/30/2017. The issue is that the definition we want is found in month 2. We never interrogate the holidays in that month/region since we are only looking at generic (i.e. easter or yearly holidays, the 0) or January holidays. We never check February holidays and thus never perform the 'observed' method for 'closest monday from 2/1/2017' and thus never get 1/30/2017.

One easy but maybe crappy solution is to grab additional months when building the dates hash. If we have 1 then we also grab 2. If we have 6 then we also grab 5 and 7. This will increase the amount of processing we do but it will guarantee that we catch month-spanning calculations.

1.0.7 problems

Hey! Just updated from 1.0.6 to 1.0.7 and something went wrong:

1.0.7:

Loading development environment (Rails 4.1.6)
2.1.1 :001 > Date.current.holiday?
NoMethodError: undefined method `holiday?' for Mon, 13 Oct 2014:Date

Seems like Holidays isn't loaded all.

1.0.6:

Loading development environment (Rails 4.1.6)
2.1.1 :001 > Date.current.holiday?
 => false 

I simply have this in my Gemfile:

gem 'holidays'

I skimmed through the change history since 1.0.6 and couldn't find anything relevant that would affect loading of Holidays.

Remote code execution when trying to load custom region

Culprit code :

regions.delete_if do |reg|
  if reg.to_s =~ /_$/
    prefix = reg.to_s.split('_').first
    unless @@regions.include?(prefix.to_sym)
      begin
        require "holidays/#{prefix}"
      rescue LoadError
        raise UnknownRegionError, "Could not load holidays/#{prefix}"
      end
    end
    regions << @@regions.select { |dr| dr.to_s =~ Regexp.new("^#{reg}") }
    true
  end
end

Let's say you can upload a file to /tmp on the server, like profile_pic.jpg that contains some ruby

Calling Holidays.between(Time.now, 2.years.from_now, '../../../../../../../../../../../../tmp/profile_pic.jpg') will execute the ruby code inside the file.

the region parameter can be something issued from a user params, hence this issue.

Thanks

Support Japanese rokuyo

In Japan there is a Buddhist calendar system called "rokuyo". More info here: http://www.seiyaku.com/customs/rokuyo.php. It is standard to see Rokuyo on most calendars printed in Japan.

The logic is complex but essentially each day has a rokuyo day which is one of 6 values, and unlike western weekdays (mon, tues, weds) they don't follow a consistent cycle and reset based on lunar month and other exceptions.

I'd like to make a new "rokuyo" file; if that's cool I'll raise a PR in the next month.

Convert to rspec?

What are people's thoughts about the current test suite? In the process of refactoring I am adding a bunch of new tests and I'm starting to wonder if I should spend the time to convert us to rspec.

I'll admit that I am partial to it over Test::Unit. It has a lot of additional features that I have come to rely upon. I'm really torn, though, because it's a lot of work and we already have working tests.

Looking for thoughts from others to help me decide.

Getting the name of a region

Hi,

I'm trying to use this in an application to mark Bank Holidays in a user's calendar.

In order to make this work I'm assuming I need to collect the region a user is in, and to do that I'm going to need a list of regions, converted to English names (at the very least, possibly I18n'ed names in the future).

Is there anyway to do that?

Also, there seems to be some regions I wouldn't want a user to select. For example, if gb_con (Cornwall) is selected, then this will no longer show Easter Monday in England, which is incorrect:

> Holidays.on(Date.parse('2016-03-28'), :gb_con)
=> []
> Holidays.on(Date.parse('2016-03-28'), :gb_eng)
=> [{:date=>Mon, 28 Mar 2016, :name=>"Easter Monday", :regions=>[:gb_eng, :gb_wls, :gb_eaw, :gb_nir]}]

Problems with easter

Holidays.easter 2012
=> Sun, 08 Apr 2012

That is all well and good but

date=Date.civil 2012, 4, 8
=> Sun, 08 Apr 2012

Holidays.on date,:us,:observed
=> []

and
date.holiday? :us
=> false


Also found weird behaviors such as:

development environment (Rails 3.2.3)
irb(main):001:0> d=Date.civil 2012,7,4
=> Wed, 04 Jul 2012
irb(main):002:0> d.holidays
=> []
irb(main):003:0> d.holidays :us
=> [{:date=>Wed, 04 Jul 2012, :name=>"Independence Day", :regions=>[:us]}]
d.holidays
=> [{:date=>Wed, 04 Jul 2012, :name=>"Independence Day", :regions=>[:us]}]

NYSE - Incorrect date for Independence day?

This year the 4th of July falls on a Saturday and is observed on Friday 3rd. However, when I run the following, the 4th is still listed as a holiday

y Holidays.between(Date.civil(2015,1,1),Date.civil(2015,12,31),:nyse)

Similarly the following returns false:

d = Date.civil(2015,7,3) d.holiday?(:nyse)

If this is a bug I'll be happy to investigate and supply a fix, but I want to confirm that I'm not missing part of the puzzle.
Thanks
Jason

NoMethodError: undefined method `holiday?'

It seems the holiday? method is broken in version 3.0.0 (although I have not tested any other versions):

gem install holidays
Fetching: holidays-3.0.0.gem (100%)
Successfully installed holidays-3.0.0
Parsing documentation for holidays-3.0.0
Installing ri documentation for holidays-3.0.0
Done installing documentation for holidays after 1 seconds
1 gem installed

irb -rpp
2.2.0 :001 > require 'holidays'
=> true
2.2.0 :002 > require 'generated_definitions/us'
=> true
2.2.0 :003 > Date.today.holiday?
NoMethodError: undefined method holiday?' for #<Date: 2015-12-16 ((2457373j,0s,0n),+0s,2299161j)> from (irb):3 from /Users/user/.rvm/rubies/ruby-2.2.0/bin/irb:11:in

'
2.2.0 :004 > require 'holidays/core_extensions/date'
=> true
2.2.0 :005 > Date.today.holiday?
NoMethodError: undefined method holiday?' for #<Date: 2015-12-16 ((2457373j,0s,0n),+0s,2299161j)> from (irb):5 from /Users/user/.rvm/rubies/ruby-2.2.0/bin/irb:11:in'
2.2.0 :006 > Date.today.holiday?(:us)
NoMethodError: undefined method holiday?' for #<Date: 2015-12-16 ((2457373j,0s,0n),+0s,2299161j)> from (irb):6 from /Users/user/.rvm/rubies/ruby-2.2.0/bin/irb:11:in'
2.2.0 :007 >

Inaguration Day isn't a Federal Reserve holiday

The federal_reserve region currently counts Inaguration Day as a holiday, but according to this it's not (just the Governors Board being closed, which doesn't count), so I think it should be removed.
Also, it doesn't look like Independence Day should be using to_monday_if_sunday.

Get next X number of holidays

Is there a way to get the next x number of holidays? I saw between, but we have a couple of uses where we'd like to get the next 2, and next 4 holidays.

Thanks

NoMethodError: undefined method `calculate_mday' for Date:Class

holidays 3.0.0 afaik

Backtrace from newrelic:

NoMethodError: undefined method `calculate_mday' for Date:Class
….0/gems/holidays-3.0.0/lib/generated_definitions/au.rb:  109:in `march_pub_hol_sa'
….0/gems/holidays-3.0.0/lib/generated_definitions/au.rb:   31:in `block in holidays_by_month'
…3.0.0/lib/holidays/definition/repository/proc_cache.rb:   30:in `call'
…3.0.0/lib/holidays/definition/repository/proc_cache.rb:   30:in `lookup'
…olidays-3.0.0/lib/holidays/use_case/context/between.rb:   81:in `call_proc'
…olidays-3.0.0/lib/holidays/use_case/context/between.rb:   28:in `block (3 levels) in call'
…olidays-3.0.0/lib/holidays/use_case/context/between.rb:   20:in `each'
…olidays-3.0.0/lib/holidays/use_case/context/between.rb:   20:in `block (2 levels) in call'
…olidays-3.0.0/lib/holidays/use_case/context/between.rb:   17:in `each'
…olidays-3.0.0/lib/holidays/use_case/context/between.rb:   17:in `block in call'
…olidays-3.0.0/lib/holidays/use_case/context/between.rb:   16:in `each'
…olidays-3.0.0/lib/holidays/use_case/context/between.rb:   16:in `call'
….bundle/ruby/2.1.0/gems/holidays-3.0.0/lib/holidays.rb:  122:in `between'
…leases/0.0.2183/app/controllers/holidays_controller.rb:    8:in `index'

Reproduce code

irb(main):003:0> Time.now
=> 2016-01-04 09:42:09 +1030
irb(main):004:0> Holidays.between(Time.now, 1.month.from_now, [:au_sa])
NoMethodError: undefined method `calculate_mday' for Date:Class
    from /home/clockwerx/.rbenv/versions/2.1.7/lib/ruby/gems/2.1.0/gems/holidays-3.0.0/lib/generated_definitions/au.rb:109:in `march_pub_hol_sa'
    from /home/clockwerx/.rbenv/versions/2.1.7/lib/ruby/gems/2.1.0/gems/holidays-3.0.0/lib/generated_definitions/au.rb:31:in `block in holidays_by_month'
    from /home/clockwerx/.rbenv/versions/2.1.7/lib/ruby/gems/2.1.0/gems/holidays-3.0.0/lib/holidays/definition/repository/proc_cache.rb:30:in `call'
    from /home/clockwerx/.rbenv/versions/2.1.7/lib/ruby/gems/2.1.0/gems/holidays-3.0.0/lib/holidays/definition/repository/proc_cache.rb:30:in `lookup'
    from /home/clockwerx/.rbenv/versions/2.1.7/lib/ruby/gems/2.1.0/gems/holidays-3.0.0/lib/holidays/use_case/context/between.rb:81:in `call_proc'
    from /home/clockwerx/.rbenv/versions/2.1.7/lib/ruby/gems/2.1.0/gems/holidays-3.0.0/lib/holidays/use_case/context/between.rb:28:in `block (3 levels) in call'
    from /home/clockwerx/.rbenv/versions/2.1.7/lib/ruby/gems/2.1.0/gems/holidays-3.0.0/lib/holidays/use_case/context/between.rb:20:in `each'
    from /home/clockwerx/.rbenv/versions/2.1.7/lib/ruby/gems/2.1.0/gems/holidays-3.0.0/lib/holidays/use_case/context/between.rb:20:in `block (2 levels) in call'
    from /home/clockwerx/.rbenv/versions/2.1.7/lib/ruby/gems/2.1.0/gems/holidays-3.0.0/lib/holidays/use_case/context/between.rb:17:in `each'
    from /home/clockwerx/.rbenv/versions/2.1.7/lib/ruby/gems/2.1.0/gems/holidays-3.0.0/lib/holidays/use_case/context/between.rb:17:in `block in call'
    from /home/clockwerx/.rbenv/versions/2.1.7/lib/ruby/gems/2.1.0/gems/holidays-3.0.0/lib/holidays/use_case/context/between.rb:16:in `each'
    from /home/clockwerx/.rbenv/versions/2.1.7/lib/ruby/gems/2.1.0/gems/holidays-3.0.0/lib/holidays/use_case/context/between.rb:16:in `call'
    from /home/clockwerx/.rbenv/versions/2.1.7/lib/ruby/gems/2.1.0/gems/holidays-3.0.0/lib/holidays.rb:122:in `between'
    from (irb):4
    from /home/clockwerx/.rbenv/versions/2.1.7/lib/ruby/gems/2.1.0/gems/railties-4.1.12/lib/rails/commands/console.rb:90:in `start'
    from /home/clockwerx/.rbenv/versions/2.1.7/lib/ruby/gems/2.1.0/gems/railties-4.1.12/lib/rails/commands/console.rb:9:in `start'
    from /home/clockwerx/.rbenv/versions/2.1.7/lib/ruby/gems/2.1.0/gems/railties-4.1.12/lib/rails/commands/commands_tasks.rb:69:in `console'
    from /home/clockwerx/.rbenv/versions/2.1.7/lib/ruby/gems/2.1.0/gems/railties-4.1.12/lib/rails/commands/commands_tasks.rb:40:in `run_command!'
    from /home/clockwerx/.rbenv/versions/2.1.7/lib/ruby/gems/2.1.0/gems/railties-4.1.12/lib/rails/commands.rb:17:in `<top (required)>'
    from bin/rails:4:in `require'
    from bin/rails:4:in `<main>'irb(main):005:0> 

Bug with german holidays

May 8 is not a german holiday:

require "holidays"
require "holidays/de"
Date.civil(2010,5,8).holiday?(:de)
=> true

should be false

Queen's Birthday and Labour Day incorrect for Queensland

Hi,

I would fix these myself but I'm not sure how, hopefully you can help!

http://www.justice.qld.gov.au/fair-and-safe-work/industrial-relations/public-holidays/dates lists public holidays in Queensland.

  • in 2012, the Queen's Birthday was observed twice, but in all other years it's only observed once. Is it possible for a holiday to be observed twice in the gem (but only in certain years)?
  • from 2013, the date of Labour Day has changed from May to October. Is there a way of having the gem reflect this?

Thanks!

It looks like mother's day and father's day are wrong in north_america.rb

I think they should be included as follows...

5 => [{:function => lambda { |year| Holidays.ca_victoria_day(year) }, :function_id => "ca_victoria_day(year)", :name => "Victoria Day", :regions => [:ca]},
{:function => lambda { |year| Holidays.ca_victoria_day(year) }, :function_id => "ca_victoria_day(year)", :name => "National Patriotes Day", :regions => [:ca_qc]},
{:mday => 1, :name => "Día del Trabajo", :regions => [:mx]},
{:mday => 5, :type => :informal, :name => "Cinco de Mayo", :regions => [:mx]},
{:mday => 5, :name => "La Batalla de Puebla", :regions => [:mx_pue]},
{:mday => 10, :type => :informal, :name => "Día de la Madre", :regions => [:mx]},
{:mday => 15, :type => :informal, :name => "Día del Maestro", :regions => [:mx]},
{:wday => 1, :week => -1, :name => "Memorial Day", :regions => [:us]},
{:wday => 0, :week => 2, :type => :informal, :name => "Mother's Day", :regions => [:us, :ca]}],
6 => [{:mday => 24, :name => "Discovery Day", :regions => [:ca_nf]},
{:mday => 24, :name => "Fête Nationale", :regions => [:ca_qc]},
{:mday => 21, :name => "National Aboriginal Day", :regions => [:ca_nt]},
{:wday => 0, :week => 3, :type => :informal, :name => "Día del Padre", :regions => [:mx]},
{:wday => 0, :week => 3, :type => :informal, :name => "Father's Day", :regions => [:us, :ca]}],

Update es.yaml [Andalucia Zone and "observed: to_monday_if_sunday"]

months:
0:

  • name: Jueves Santo
    regions: [es_pv, es_ct, es_na, es_v, es_vc, es_an]
    function: easter(year)-3

  • name: Viernes Santo
    regions: [es]
    function: easter(year)-2

  • name: Lunes de Pascua
    regions: [es_pv, es_ct, es_na, es_v, es_vc]
    function: easter(year)+1
    1:

  • name: Año Nuevo
    regions: [es]
    mday: 1
    observed: to_monday_if_sunday

  • name: Día de Reyes
    regions: [es]
    mday: 6
    observed: to_monday_if_sunday
    2:

  • name: Día de Andalucía
    regions: [es_an]
    mday: 28
    observed: to_monday_if_sunday
    3:

  • name: Día de las Islas Baleares
    regions: [es_ib]
    mday: 1
    observed: to_monday_if_sunday

  • name: San José
    regions: [es_v, es_vc, es_cm, es_mu, es_m]
    mday: 19
    observed: to_monday_if_sunday
    4:

  • name: San Jorge
    regions: [es_ar, es_cl]
    mday: 23
    observed: to_monday_if_sunday

  • name: Día de Aragón
    regions: [es_ar]
    mday: 23
    observed: to_monday_if_sunday
    5:

  • name: Día del Trabajador
    regions: [es]
    mday: 1
    observed: to_monday_if_sunday

  • name: Fiesta de la Comunidad
    regions: [es_m]
    mday: 2
    observed: to_monday_if_sunday

  • name: Día de las Canarias
    regions: [es_cn]
    mday: 30
    observed: to_monday_if_sunday

  • name: Día de la Región Castilla-La Mancha
    regions: [es_cm]
    mday: 31
    observed: to_monday_if_sunday
    6:

  • name: Día de la Región de Murcia
    regions: [es_mu]
    mday: 9
    observed: to_monday_if_sunday

  • name: Día de La Rioja
    regions: [es_lo]
    mday: 9
    observed: to_monday_if_sunday
    7:

  • name: Santiago Apostol
    regions: [es_ga]
    mday: 23
    observed: to_monday_if_sunday
    8:

  • name: Asunción
    regions: [es]
    mday: 15
    observed: to_monday_if_sunday
    9:

  • name: Día de Ceuta
    regions: [es_ce]
    mday: 2
    observed: to_monday_if_sunday

  • name: Día de Asturias
    regions: [es_o]
    mday: 8
    observed: to_monday_if_sunday

  • name: Día de Extremadura
    regions: [es_ex]
    mday: 8

  • name: Fiesta Nacional de Cataluña
    regions: [es_ct]
    mday: 11
    observed: to_monday_if_sunday
    10:

  • name: Día de Valencia
    regions: [es_vc, es_v]
    mday: 9
    observed: to_monday_if_sunday

  • name: Día de la Hispanidad
    regions: [es]
    mday: 12
    observed: to_monday_if_sunday
    11:

  • name: Todos los Santos
    regions: [es]
    mday: 1
    observed: to_monday_if_sunday
    12:

  • name: Día de la Constitución
    regions: [es]
    mday: 6
    observed: to_monday_if_sunday

  • name: Inmaculada Concepción
    regions: [es]
    mday: 8
    observed: to_monday_if_sunday

  • name: Navidad del Señor
    regions: [es]
    mday: 25
    observed: to_monday_if_sunday

  • name: San Esteban
    regions: [es_ib, es_ct]
    mday: 26
    observed: to_monday_if_sunday
    tests: |
    {Date.civil(2009,1,1) => 'Año Nuevo',
    Date.civil(2009,1,6) => 'Día de Reyes',
    Date.civil(2009,4,10) => 'Viernes Santo',
    Date.civil(2009,5,1) => 'Día del Trabajador',
    Date.civil(2009,8,15) => 'Asunción',
    Date.civil(2009,10,12) => 'Día de la Hispanidad',
    Date.civil(2009,11,1) => 'Todos los Santos',
    Date.civil(2009,12,6) => 'Día de la Constitución',
    Date.civil(2009,12,8) => 'Inmaculada Concepción',
    Date.civil(2009,12,25) => 'Navidad del Señor'}.each do |date, name|
    assert_equal name, (Holidays.on(date, :es, :informal)[0] || {})[:name]
    end

    [:es_pv, :es_ct, :es_na, :es_v, :es_vc, :es_].each do |r|
    assert_equal 'Jueves Santo', Date.civil(2009,4,9).holidays(r)[0][:name]
    assert_equal 'Lunes de Pascua', Date.civil(2009,4,13).holidays(r)[0][:name]
    end

    [:es_v, :es_vc, :es_cm, :es_mu, :es_m, :es_].each do |r|
    assert_equal 'San José', Date.civil(2009,3,19).holidays(r)[0][:name]
    end

    [:es_ar, :es_cl, :es_].each do |r|
    assert_equal 'San Jorge', Date.civil(2009,4,23).holidays(r)[0][:name]
    end

    [:es_vc, :es_v, :es_].each do |r|
    assert_equal 'Día de Valencia', Date.civil(2009,10,9).holidays(r)[0][:name]
    end

    [:es_ib, :es_ct, :es_].each do |r|
    assert_equal 'San Esteban', Date.civil(2009,12,26).holidays(r)[0][:name]
    end

    assert_equal 'Día de Andalucía', Date.civil(2009,2,28).holidays(:es_an)[0][:name]
    assert_equal 'Día de las Islas Baleares', Date.civil(2009,3,1).holidays(:es_ib)[0][:name]
    assert_equal 'Fiesta de la Comunidad', Date.civil(2006,5,2).holidays(:es_m)[0][:name]
    assert_equal 'Día de las Canarias', Date.civil(2006,5,30).holidays(:es_cn)[0][:name]
    assert_equal 'Día de la Región Castilla-La Mancha', Date.civil(2009,5,31).holidays(:es_cm)[0][:name]
    assert_equal 'Día de la Región de Murcia', Date.civil(2009,6,9).holidays(:es_mu)[0][:name]
    assert_equal 'Día de La Rioja', Date.civil(2009,6,9).holidays(:es_lo)[0][:name]
    assert_equal 'Santiago Apostol', Date.civil(2009,7,23).holidays(:es_ga)[0][:name]
    assert_equal 'Día de Ceuta', Date.civil(2009,9,2).holidays(:es_ce)[0][:name]
    assert_equal 'Día de Asturias', Date.civil(2009,9,8).holidays(:es_o)[0][:name]
    assert_equal 'Día de Extremadura', Date.civil(2009,9,8).holidays(:es_ex)[0][:name]
    assert_equal 'Fiesta Nacional de Cataluña', Date.civil(2009,9,11).holidays(:es_ct)[0][:name]

Add Coverage support

We should be tracking test coverage.

FYI, while investigating this I discovered that we still support Ruby 1.8.7 , which is so out of date that it should probably be dropped as part of this change.

Western Australia (:au_wa) ANZAC Day 2015 not on Monday

Although technically the public holiday is both Saturday 25th April and Monday 27th April (as per http://www.commerce.wa.gov.au/labour-relations/public-holidays-western-australia), the rule of "to_monday_if_weekend" is not working. Instead I'm seeing the following (all loaded):

{:date=>Sat, 25 Apr 2015, :name=>"ANZAC Day", :regions=>[:au]}
{:date=>Sat, 25 Apr 2015, :name=>"ANZAC Day", :regions=>[:au_nsw, :au_vic, :au_qld, :au_nt, :au_act, :au_sa, :au_tas]}
{:date=>Sat, 25 Apr 2015, :name=>"ANZAC Day", :regions=>[:au_wa, :nz]}

NZ Nelson Anniversary

First off - thanks for your work on this awesome gem.

The NZ region file includes the Nelson Anniversary, but has the region as :nz_ak - which is Auckland (other end of the country, and has its own anniversary! - see here and here)

https://github.com/holidays/holidays/blob/master/data/nz.yaml#L42

The same goes for Taranaki, which is closer but still a separate region. According to the yml file, its anniversary also incorrectly falls under :nz_ak.

It's not clear which is the Nelson region - :nz_nl seems to be for Northland. I'd be happy to make a change to the data files themselves, but not confident I'd test them properly. Based on how I think things work, it might look something like:

2:
  - name: Nelson Anniversary Day
  regions: [nz_ne]
  mday: 1
  observed: closest_monday

and

3:
  - name: Taranaki Anniversary Day
  regions: [nz_ta]
  week: 2
  wday: 1
  observed: closest_monday

Thanks muchly!

Issue in identifying holidays for region :ca when used in Rails application in production mode

The gem is working perfectly fine in development mode when cache_classes is set to false. However, when in production mode gem fails to recognize the Canadian holidays e.g New year's day. I made some initial investigation and found that.

  1. In production mode holiday definitions for US (holidays/us.rb) is getting loaded by default which is not happening in development mode
  2. In us.rb we have regions specified as [:us, :us_dc, :ca].
  3. Due to this, when we try to find a holiday for :ca, the holidays/ca.rb is not loaded since in @@Regions we have [:us, :us_dc, :ca]

Line 342 of holidays.rb file
raise UnknownRegionError unless regions.all? { |r| r == :any or @@regions.include?(r) or begin require "holidays/#{r.to_s}"; rescue LoadError; false; end }

I believe we should we should have this modified to load the holiday definitions file if not loaded as follows (Just changed the order of condition)

raise UnknownRegionError unless regions.all? { |r| r == :any or begin require "holidays/#{r.to_s}"; rescue LoadError; false; end or @@regions.include?(r)}

Also, why do we have :ca region specified in holidays/us.rb holiday definition file?

Can't load function based holidays with .load_custom

When I tried to add a custom holiday using a yaml file as per the Readme instructions, I got a NoMethodError: undefined method call' for "easter(year)-47":String error.

Holidays.call_proc is waiting for a Proc, but when the yaml is loaded by .load_custom, function nodes are are sent to .call_proc as regular Strings.

I didn't dive into the code much, but I implemented a solution that didn't break any tests. Maybe there's a better way of doing this.

module Holidays
  def self.call_proc(function, year) # :nodoc:
    proc_key = Digest::MD5.hexdigest("#{function.to_s}_#{year.to_s}")
    @@proc_cache[proc_key] = string_to_proc(function).call(year) unless @@proc_cache[proc_key]
    @@proc_cache[proc_key]
  end

  def self.string_to_proc(function)
    function.is_a?(String) ? Proc.new{ |year| eval(function) } : function 
  end
end

How to override holidays

We're using the holidays gem to prevent performing actions on holidays, but some holidays defined in the yaml files, such as liberation day, is an normal working day.

I know how to add custom holidays, but how can i override a specific holiday?

Add new region - Bulgaria

Hi,
It will be very nice if the Bulgarian holidays are added. I've prepared "bg.yaml" that is tested. It seems it is working fine. The problem is that the Orthodox Easter is calculated according the Julian calender -> http://en.wikipedia.org/wiki/Easter. I found this functionality implemented in project https://github.com/Loyolny/when_easter, so I used it. Maybe you could implement the same code for the Orthodox Easter calculations or just use the plug in.
How can I send you the yaml file?
Best regards!

Changing regions names to be I18n compliant

Hi, I'm using the holidays gem and was wondering if it doesn't worth it to change the regions names to be I18n compliant. For example, instead of br we would have pt-BR. In this way, we could check the holidays just passing the I18n.locale as a region parameter.
By the way, I can implement this change.
Thoughts?

Holidays::UnknownRegionError for :europe

Hi,

I am using version 1.0.5 of the gem and ever since the 30th have starting seeing a very odd issue (I wonder whether it could be related to the UK entering British Summer Time?)

Anyway:

Loading development environment (Rails 3.2.13)
irb(main):001:0> Holidays.on(Date.parse("2013-03-01"), :europe)
=> []
irb(main):002:0> Holidays.on(Date.parse("2013-03-01"), :europe)
Holidays::UnknownRegionError: Holidays::UnknownRegionError
    from /var/lib/gems/1.9.1/bundler/gems/holidays-a365bba33b76/lib/holidays.rb:342:in `parse_regions'
    from /var/lib/gems/1.9.1/bundler/gems/holidays-a365bba33b76/lib/holidays.rb:313:in `parse_options'
    from /var/lib/gems/1.9.1/bundler/gems/holidays-a365bba33b76/lib/holidays.rb:124:in `between'
    from /var/lib/gems/1.9.1/bundler/gems/holidays-a365bba33b76/lib/holidays.rb:70:in `on'
    from (irb):2
    from /var/lib/gems/1.9.1/gems/railties-3.2.13/lib/rails/commands/console.rb:47:in `start'
    from /var/lib/gems/1.9.1/gems/railties-3.2.13/lib/rails/commands/console.rb:8:in `start'
    from /var/lib/gems/1.9.1/gems/railties-3.2.13/lib/rails/commands.rb:41:in `<top (required)>'
    from script/rails:6:in `require'
    from script/rails:6:in `<main>'

Any idea what is going on here? All other regions appear to work fine.

best way of configuring existing and new holidays?

I'd like to remove some holidays that are defined in us.yml, and add some new ones. I only want to do this for usage at our organization. I'd also like to have these changes reflected on our heroku deploy. I really don't want to fork the gem, nor do I really want to unpack it and modify it locally. What's the ideal way to use the standard gem, but customize holidays using the yml files? It's not clear to me how to do this.

Certain Canada holidays should be restricted by year

According to comments left in the Canadian definitions there seem to be certain holidays that should only apply after a certain year. We now have this functionality so we should update the definitions to make them more accurate.

Holidays in question:

New tests should be added to confirm that it gives the proper answers both before and after the cutoff.

GB holidays

I think the code to roll christmas day and boxing day for UK holidays isn't quite right.

If Christmas day falls on a Saturday, then it will be _observed _ on Monday 27th Dec, with Boxing day observed on Tuesday 28th Dec.

If Christmas day falls on a Sunday, it will be observed on the Monday (26th Dec), with Boxing day observed on the Tuesday 27th.

I believe these cases do not work at the moment.

Carnaval not working

Hi Alex,

If i do this:
date = Date.civil(2011,3,8)

(Holidays.on(date, :br, :informal))
=> [{:date=>Mon, 08 Mar 2011, :name=>"Carnaval", :regions=>[:br]}]

but

Date.civil(2011,3,8).holiday?(:br)

gives me: false...

thanks!

Using:

Rails 3.0.7
ruby-1.9.2-p136

Add Code of Conduct

I know this is a small project but I feel strongly that a Code of Conduct should be added if for no other reason than to indicate my overt support for a friendly, open, and cooperative open source community.

I'll be adding something along the lines of the Contributor Covenant in the coming weeks. I'm only waiting because I have a good head of steam going in my current work and don't want to lose that momentum. 😄

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.