holidays 4.4.0 → 4.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +4 -0
- data/README.md +16 -0
- data/lib/holidays.rb +44 -0
- data/lib/holidays/core_extensions/date.rb +18 -0
- data/lib/holidays/core_extensions/time.rb +23 -0
- data/lib/holidays/use_case/context/year_holiday.rb +51 -0
- data/lib/holidays/use_case_factory.rb +10 -0
- data/lib/holidays/version.rb +1 -1
- data/test/holidays/core_extensions/test_date_time.rb +60 -0
- data/test/test_helper.rb +5 -0
- data/test/test_holidays.rb +55 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cb0c1c87e82d392d31c5281d907e58bbe6573683
|
4
|
+
data.tar.gz: 7ffb3aa2717b7727898810687778f0df10ec235f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 7f5373bd6b450b42b4a9bb28338c028faecc3a3aea2c52146cd092fbf5ee6b2a144cf00450a5ddd430532737c46c1da590f387e45ddcfb2ca6584903844b4b53
|
7
|
+
data.tar.gz: cbaeda3492a457b84d3f2d0d19a8080539fbdf3068aa722e8593a42597897fddf767ba2bbb2668bc2a5a42c254e2f3ae1ad69a36362e9c2f52f925429bda6d90
|
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
# Ruby Holidays Gem CHANGELOG
|
2
2
|
|
3
|
+
## 4.5.0
|
4
|
+
|
5
|
+
* Add `Holidays.year_holidays` method to obtain all holidays occuring from date to end of year, inclusively (thanks to https://github.com/jonathanpike)
|
6
|
+
|
3
7
|
## 4.4.0
|
4
8
|
|
5
9
|
* Add Peruvian holiday definitions (https://github.com/Xosmond)
|
data/README.md
CHANGED
@@ -72,6 +72,22 @@ To find and return the next holidays occurring from date, inclusively:
|
|
72
72
|
|
73
73
|
Will default to `Date.today` if no date is provided.
|
74
74
|
|
75
|
+
To find all holidays occuring from date to end of year, inclusively:
|
76
|
+
|
77
|
+
Holidays.year_holidays([:ca_on], Date.civil(2016, 2, 23))
|
78
|
+
=> [{:name=>"Good Friday",...},
|
79
|
+
{name=>"Easter Sunday",...},
|
80
|
+
{:name=>"Victoria Day",...},
|
81
|
+
{:name=>"Canada Day",...},
|
82
|
+
{:name=>"Civic Holiday",...},
|
83
|
+
{:name=>"Labour Day",...},
|
84
|
+
{:name=>"Thanksgiving",...},
|
85
|
+
{:name=>"Remembrance Day",...},
|
86
|
+
{:name=>"Christmas Day",...},
|
87
|
+
{:name=>"Boxing Day",...}]
|
88
|
+
|
89
|
+
Will default to `Date.today` if no date is provided.
|
90
|
+
|
75
91
|
### Loading Custom Definitions on the fly
|
76
92
|
|
77
93
|
Load custom definitions file on the fly and use them immediately.
|
data/lib/holidays.rb
CHANGED
@@ -160,6 +160,50 @@ module Holidays
|
|
160
160
|
UseCaseFactory.next_holiday.call(holidays_count, from_date, date_driver_hash, regions, observed, informal)
|
161
161
|
end
|
162
162
|
|
163
|
+
# Get all holidays occuring from date to end of year, inclusively.
|
164
|
+
#
|
165
|
+
# Returns an array of hashes or nil.
|
166
|
+
#
|
167
|
+
# Incoming arguments are below:
|
168
|
+
# [<tt>options</tt>] One or more region symbols, <tt>:informal</tt> and/or <tt>:observed</tt>.
|
169
|
+
# [<tt>from_date</tt>] Ruby Date object. This is an optional param, defaulted today.
|
170
|
+
#
|
171
|
+
# ==== Example
|
172
|
+
# Date.today
|
173
|
+
# => Tue, 23 Feb 2016
|
174
|
+
#
|
175
|
+
# regions = [:ca_on]
|
176
|
+
#
|
177
|
+
# Holidays.year_holidays(regions)
|
178
|
+
# => [{:name=>"Good Friday",...},
|
179
|
+
# {name=>"Easter Sunday",...},
|
180
|
+
# {:name=>"Victoria Day",...},
|
181
|
+
# {:name=>"Canada Day",...},
|
182
|
+
# {:name=>"Civic Holiday",...},
|
183
|
+
# {:name=>"Labour Day",...},
|
184
|
+
# {:name=>"Thanksgiving",...},
|
185
|
+
# {:name=>"Remembrance Day",...},
|
186
|
+
# {:name=>"Christmas Day",...},
|
187
|
+
# {:name=>"Boxing Day",...}]
|
188
|
+
def year_holidays(options, from_date = Date.today)
|
189
|
+
raise ArgumentError if options.empty?
|
190
|
+
raise ArgumentError unless options.is_a?(Array)
|
191
|
+
|
192
|
+
# remove the timezone
|
193
|
+
from_date = from_date.new_offset(0) + from_date.offset if from_date.respond_to?(:new_offset)
|
194
|
+
|
195
|
+
from_date = get_date(from_date)
|
196
|
+
to_date = Date.new(from_date.year, 12, 31)
|
197
|
+
regions, observed, informal = OptionFactory.parse_options.call(options)
|
198
|
+
|
199
|
+
# This could be smarter but I don't have any evidence that just checking for
|
200
|
+
# the next 12 months will cause us issues. If it does we can implement something
|
201
|
+
# smarter here to check in smaller increments.
|
202
|
+
date_driver_hash = UseCaseFactory.dates_driver_builder.call(from_date, from_date >> 12)
|
203
|
+
|
204
|
+
UseCaseFactory.year_holiday.call(from_date, to_date, date_driver_hash, regions, observed, informal)
|
205
|
+
end
|
206
|
+
|
163
207
|
# Allows a developer to explicitly calculate and cache holidays within a given period
|
164
208
|
def cache_between(start_date, end_date, *options)
|
165
209
|
start_date, end_date = get_date(start_date), get_date(end_date)
|
@@ -29,6 +29,24 @@ module Holidays
|
|
29
29
|
holidays && !holidays.empty?
|
30
30
|
end
|
31
31
|
|
32
|
+
# Returns a new Date where one or more of the elements have been changed according to the +options+ parameter.
|
33
|
+
# The +options+ parameter is a hash with a combination of these keys: <tt>:year</tt>, <tt>:month</tt>, <tt>:day</tt>.
|
34
|
+
#
|
35
|
+
# Date.new(2007, 5, 12).change(day: 1) # => Date.new(2007, 5, 1)
|
36
|
+
# Date.new(2007, 5, 12).change(year: 2005, month: 1) # => Date.new(2005, 1, 12)
|
37
|
+
def change(options)
|
38
|
+
::Date.new(
|
39
|
+
options.fetch(:year, year),
|
40
|
+
options.fetch(:month, month),
|
41
|
+
options.fetch(:day, day)
|
42
|
+
)
|
43
|
+
end
|
44
|
+
|
45
|
+
def end_of_month
|
46
|
+
last_day = ::Time.days_in_month( self.month, self.year )
|
47
|
+
change(:day => last_day)
|
48
|
+
end
|
49
|
+
|
32
50
|
module ClassMethods
|
33
51
|
def calculate_mday(year, month, week, wday)
|
34
52
|
Holidays::DateCalculatorFactory.day_of_month_calculator.call(year, month, week, wday)
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Holidays
|
2
|
+
module CoreExtensions
|
3
|
+
module Time
|
4
|
+
def self.included(base)
|
5
|
+
base.extend ClassMethods
|
6
|
+
end
|
7
|
+
|
8
|
+
module ClassMethods
|
9
|
+
COMMON_YEAR_DAYS_IN_MONTH = [nil, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
|
10
|
+
|
11
|
+
# Returns the number of days in the given month.
|
12
|
+
# If no year is specified, it will use the current year.
|
13
|
+
def days_in_month(month, year = current.year)
|
14
|
+
if month == 2 && ::Date.gregorian_leap?(year)
|
15
|
+
29
|
16
|
+
else
|
17
|
+
COMMON_YEAR_DAYS_IN_MONTH[month]
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
module Holidays
|
2
|
+
module UseCase
|
3
|
+
module Context
|
4
|
+
class YearHoliday
|
5
|
+
include ContextCommon
|
6
|
+
|
7
|
+
def initialize(holidays_by_month_repo, day_of_month_calculator, custom_methods_repo, proc_result_cache_repo)
|
8
|
+
@holidays_by_month_repo = holidays_by_month_repo
|
9
|
+
@day_of_month_calculator = day_of_month_calculator
|
10
|
+
@custom_methods_repo = custom_methods_repo
|
11
|
+
@proc_result_cache_repo = proc_result_cache_repo
|
12
|
+
end
|
13
|
+
|
14
|
+
def call(from_date, to_date, dates_driver, regions, observed, informal)
|
15
|
+
validate!(from_date, to_date, dates_driver, regions)
|
16
|
+
holidays = []
|
17
|
+
ret_holidays = []
|
18
|
+
|
19
|
+
ret_holidays = make_date_array(dates_driver, regions, observed, informal)
|
20
|
+
ret_holidays.each do |holiday|
|
21
|
+
if holiday[:date] >= from_date && holiday[:date] <= to_date
|
22
|
+
holidays << holiday
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
holidays.sort{|a, b| a[:date] <=> b[:date] }
|
27
|
+
end
|
28
|
+
|
29
|
+
private
|
30
|
+
|
31
|
+
attr_reader :holidays_by_month_repo,
|
32
|
+
:day_of_month_calculator,
|
33
|
+
:custom_methods_repo,
|
34
|
+
:proc_result_cache_repo
|
35
|
+
|
36
|
+
def validate!(from_date, to_date, dates_driver, regions)
|
37
|
+
raise ArgumentError unless from_date
|
38
|
+
raise ArgumentError unless to_date
|
39
|
+
|
40
|
+
raise ArgumentError if dates_driver.nil? || dates_driver.empty?
|
41
|
+
|
42
|
+
dates_driver.each do |year, months|
|
43
|
+
raise ArgumentError if months.nil? || months.empty?
|
44
|
+
end
|
45
|
+
|
46
|
+
raise ArgumentError if regions.nil? || regions.empty?
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -2,6 +2,7 @@ require 'holidays/use_case/context/context_common'
|
|
2
2
|
require 'holidays/use_case/context/between'
|
3
3
|
require 'holidays/use_case/context/next_holiday'
|
4
4
|
require 'holidays/use_case/context/dates_driver_builder'
|
5
|
+
require 'holidays/use_case/context/year_holiday'
|
5
6
|
|
6
7
|
module Holidays
|
7
8
|
class UseCaseFactory
|
@@ -23,6 +24,15 @@ module Holidays
|
|
23
24
|
)
|
24
25
|
end
|
25
26
|
|
27
|
+
def year_holiday
|
28
|
+
UseCase::Context::YearHoliday.new(
|
29
|
+
DefinitionFactory.holidays_by_month_repository,
|
30
|
+
DateCalculatorFactory.day_of_month_calculator,
|
31
|
+
DefinitionFactory.custom_methods_repository,
|
32
|
+
DefinitionFactory.proc_result_cache_repository,
|
33
|
+
)
|
34
|
+
end
|
35
|
+
|
26
36
|
def dates_driver_builder
|
27
37
|
UseCase::Context::DatesDriverBuilder.new
|
28
38
|
end
|
data/lib/holidays/version.rb
CHANGED
@@ -0,0 +1,60 @@
|
|
1
|
+
require File.expand_path(File.dirname(__FILE__)) + '/../../test_helper'
|
2
|
+
|
3
|
+
require 'holidays/core_extensions/date'
|
4
|
+
require 'holidays/core_extensions/time'
|
5
|
+
|
6
|
+
class Date
|
7
|
+
include Holidays::CoreExtensions::Date
|
8
|
+
end
|
9
|
+
|
10
|
+
class Time
|
11
|
+
include Holidays::CoreExtensions::Time
|
12
|
+
end
|
13
|
+
|
14
|
+
class CoreExtensionDateTimeTests < Test::Unit::TestCase
|
15
|
+
def setup
|
16
|
+
@date = Date.civil(2008,1,1)
|
17
|
+
end
|
18
|
+
|
19
|
+
def test_change_method
|
20
|
+
actual = @date.change(day: 5)
|
21
|
+
assert_equal Date.civil(2008,1,5), actual
|
22
|
+
|
23
|
+
actual = @date.change(year: 2016)
|
24
|
+
assert_equal Date.civil(2016,1,1), actual
|
25
|
+
|
26
|
+
actual = @date.change(month: 5)
|
27
|
+
assert_equal Date.civil(2008,5,1), actual
|
28
|
+
|
29
|
+
actual = @date.change(year: 2015, month: 5, day: 3)
|
30
|
+
assert_equal Date.civil(2015,5,3), actual
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_end_of_month_method
|
34
|
+
# Works for month with 31 days
|
35
|
+
actual = @date.end_of_month
|
36
|
+
assert_equal Date.civil(2008,1,31), actual
|
37
|
+
|
38
|
+
# Works for month with 30 days
|
39
|
+
actual = Date.civil(2008,9,5).end_of_month
|
40
|
+
assert_equal Date.civil(2008,9,30), actual
|
41
|
+
|
42
|
+
# Works for leap year
|
43
|
+
actual = Date.civil(2016,2,1).end_of_month
|
44
|
+
assert_equal = Date.civil(2016,2,29), actual
|
45
|
+
end
|
46
|
+
|
47
|
+
def test_days_in_month_method
|
48
|
+
# Works for month with 31 days
|
49
|
+
actual = Time.days_in_month(1, 2008)
|
50
|
+
assert_equal 31, actual
|
51
|
+
|
52
|
+
# Works for month with 30 days
|
53
|
+
actual = Time.days_in_month(9, 2008)
|
54
|
+
assert_equal 30, actual
|
55
|
+
|
56
|
+
# Works for leap year
|
57
|
+
actual = Time.days_in_month(2, 2016)
|
58
|
+
assert_equal 29, actual
|
59
|
+
end
|
60
|
+
end
|
data/test/test_helper.rb
CHANGED
@@ -11,12 +11,17 @@ require 'mocha/test_unit'
|
|
11
11
|
require 'date'
|
12
12
|
require 'holidays'
|
13
13
|
require 'holidays/core_extensions/date'
|
14
|
+
require 'holidays/core_extensions/time'
|
14
15
|
|
15
16
|
# Loads core extension for use in various definition tests as necessary
|
16
17
|
class Date
|
17
18
|
include Holidays::CoreExtensions::Date
|
18
19
|
end
|
19
20
|
|
21
|
+
class Time
|
22
|
+
include Holidays::CoreExtensions::Time
|
23
|
+
end
|
24
|
+
|
20
25
|
module Holidays
|
21
26
|
# Test region used for generating a holiday on Date.today
|
22
27
|
module Test # :nodoc:
|
data/test/test_holidays.rb
CHANGED
@@ -139,6 +139,61 @@ class HolidaysTests < Test::Unit::TestCase
|
|
139
139
|
end
|
140
140
|
end
|
141
141
|
|
142
|
+
def test_year_holidays
|
143
|
+
# Should return 10 holidays from February 23 to December 31
|
144
|
+
holidays = Holidays.year_holidays([:ca_on], Date.civil(2016, 2, 23))
|
145
|
+
assert_equal 10, holidays.length
|
146
|
+
|
147
|
+
# Must have options (Regions)
|
148
|
+
assert_raises ArgumentError do
|
149
|
+
Holidays.year_holidays([], Date.civil(2016, 2, 23))
|
150
|
+
end
|
151
|
+
|
152
|
+
# Options must be in the form of an array.
|
153
|
+
assert_raises ArgumentError do
|
154
|
+
Holidays.year_holidays(:ca_on, Date.civil(2016, 2, 23))
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
def test_year_holidays_with_specified_year
|
159
|
+
# Should return all 12 holidays for 2016 in Ontario, Canada
|
160
|
+
holidays = Holidays.year_holidays([:ca_on], Date.civil(2016, 1, 1))
|
161
|
+
assert_equal 12, holidays.length
|
162
|
+
|
163
|
+
# Should return all 12 holidays for 2016 in Australia
|
164
|
+
holidays = Holidays.year_holidays([:au], Date.civil(2016, 1, 1))
|
165
|
+
assert_equal 5, holidays.length
|
166
|
+
end
|
167
|
+
|
168
|
+
def test_year_holidays_without_specified_year
|
169
|
+
# Gets holidays for current year from today's date
|
170
|
+
holidays = Holidays.year_holidays([:ca_on])
|
171
|
+
assert_equal holidays.first[:date].year, Date.today.year
|
172
|
+
end
|
173
|
+
|
174
|
+
def test_year_holidays_feb_29_on_non_leap_year
|
175
|
+
# Should throw argument error for invalid date
|
176
|
+
assert_raises ArgumentError do
|
177
|
+
Holidays.year_holidays([:ca_on], Date.civil(2015, 2, 29))
|
178
|
+
end
|
179
|
+
end
|
180
|
+
|
181
|
+
def test_year_holidays_random_years
|
182
|
+
# Should be 1 less holiday, as Family day didn't exist in Ontario in 1990
|
183
|
+
holidays = Holidays.year_holidays([:ca_on], Date.civil(1990, 1, 1))
|
184
|
+
assert_equal 11, holidays.length
|
185
|
+
|
186
|
+
# Family day still didn't exist in 2000
|
187
|
+
holidays = Holidays.year_holidays([:ca_on], Date.civil(2000, 1, 1))
|
188
|
+
assert_equal 11, holidays.length
|
189
|
+
|
190
|
+
holidays = Holidays.year_holidays([:ca_on], Date.civil(2020, 1, 1))
|
191
|
+
assert_equal 12, holidays.length
|
192
|
+
|
193
|
+
holidays = Holidays.year_holidays([:ca_on], Date.civil(2050, 1, 1))
|
194
|
+
assert_equal 12, holidays.length
|
195
|
+
end
|
196
|
+
|
142
197
|
def test_sub_regions
|
143
198
|
# Should return Victoria Day.
|
144
199
|
holidays = Holidays.between(Date.civil(2008,5,1), Date.civil(2008,5,31), :ca)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: holidays
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 4.
|
4
|
+
version: 4.5.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Dunae
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2016-06-
|
12
|
+
date: 2016-06-23 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -230,6 +230,7 @@ files:
|
|
230
230
|
- lib/generated_definitions/za.rb
|
231
231
|
- lib/holidays.rb
|
232
232
|
- lib/holidays/core_extensions/date.rb
|
233
|
+
- lib/holidays/core_extensions/time.rb
|
233
234
|
- lib/holidays/date_calculator/day_of_month.rb
|
234
235
|
- lib/holidays/date_calculator/easter.rb
|
235
236
|
- lib/holidays/date_calculator/weekend_modifier.rb
|
@@ -256,6 +257,7 @@ files:
|
|
256
257
|
- lib/holidays/use_case/context/context_common.rb
|
257
258
|
- lib/holidays/use_case/context/dates_driver_builder.rb
|
258
259
|
- lib/holidays/use_case/context/next_holiday.rb
|
260
|
+
- lib/holidays/use_case/context/year_holiday.rb
|
259
261
|
- lib/holidays/use_case_factory.rb
|
260
262
|
- lib/holidays/version.rb
|
261
263
|
- test/data/test_custom_govt_holiday_defs.yaml
|
@@ -320,6 +322,7 @@ files:
|
|
320
322
|
- test/defs/test_defs_vi.rb
|
321
323
|
- test/defs/test_defs_za.rb
|
322
324
|
- test/holidays/core_extensions/test_date.rb
|
325
|
+
- test/holidays/core_extensions/test_date_time.rb
|
323
326
|
- test/holidays/date_calculator/test_day_of_month.rb
|
324
327
|
- test/holidays/date_calculator/test_easter_gregorian.rb
|
325
328
|
- test/holidays/date_calculator/test_easter_julian.rb
|
@@ -437,6 +440,7 @@ test_files:
|
|
437
440
|
- test/defs/test_defs_vi.rb
|
438
441
|
- test/defs/test_defs_za.rb
|
439
442
|
- test/holidays/core_extensions/test_date.rb
|
443
|
+
- test/holidays/core_extensions/test_date_time.rb
|
440
444
|
- test/holidays/date_calculator/test_day_of_month.rb
|
441
445
|
- test/holidays/date_calculator/test_easter_gregorian.rb
|
442
446
|
- test/holidays/date_calculator/test_easter_julian.rb
|