national_holidays 0.0.1 → 0.0.2
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/LICENSE.txt +21 -0
- data/README.md +95 -0
- data/Rakefile +10 -0
- data/lib/national_holidays/country.rb +30 -0
- data/lib/national_holidays/holiday.rb +17 -0
- data/lib/national_holidays/region.rb +84 -0
- data/test/test_national_holidays.rb +24 -0
- data/test/test_national_holidays_country.rb +19 -0
- data/test/test_national_holidays_holiday.rb +30 -0
- data/test/test_national_holidays_region.rb +48 -0
- metadata +12 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cb7291b45904d9a8e6eabe11401ebcc3177e7385
|
4
|
+
data.tar.gz: 5bed83c2b535c5461d6d59f75278cf972e12b54a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: b36421e48049f73133c21313a9177f9dccbf019ecc767c4671fc8adfd4de2100536cb3b9b411a2bc4fe4a82657b3a63c41c18d0bee8b73793140d44dfc090b80
|
7
|
+
data.tar.gz: 00e0e05e3b837d264e8f7b48ff8ff6c2f006dcf103fdedf73e1a78c0bf29df559b4e422a5ebcb7db8313b680d6ee1c95ce5692aed6e1d893c67b58cf5136828a
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
MIT License
|
2
|
+
|
3
|
+
Copyright (c) [2018] [CharlieHR]
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
7
|
+
in the Software without restriction, including without limitation the rights
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
10
|
+
furnished to do so, subject to the following conditions:
|
11
|
+
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
13
|
+
copies or substantial portions of the Software.
|
14
|
+
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
21
|
+
SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,95 @@
|
|
1
|
+
# National Holidays for Ruby
|
2
|
+
|
3
|
+
## Where does this data come from?
|
4
|
+
|
5
|
+
The national holidays data used in this gem comes from the [national-holidays-config](https://github.com/kaoru/national-holidays-config) project.
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
gem install national_holidays
|
10
|
+
|
11
|
+
## Usage
|
12
|
+
|
13
|
+
require 'national_holidays'
|
14
|
+
|
15
|
+
NationalHolidays.load! # optionally pre-load all data
|
16
|
+
|
17
|
+
NationalHolidays.countries.each do |country|
|
18
|
+
country.regions.each do |region|
|
19
|
+
holidays = region.all_holidays.select { |h| h.date.day == 18 && h.date.month == 11 }
|
20
|
+
|
21
|
+
if holidays.any?
|
22
|
+
puts "My birthday is a public holiday in #{country.name}: #{holidays.first.names.except(:en).first.last}!"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
# My birthday is a public holiday in Haiti: Vertières Day!
|
28
|
+
# My birthday is a public holiday in Iran (Islamic Republic of): Martyrdom of Imam Reza!
|
29
|
+
# My birthday is a public holiday in Latvia: Latvijas Republikas proklamēšanas diena!
|
30
|
+
# My birthday is a public holiday in Mexico: Revolución Mexicana!
|
31
|
+
|
32
|
+
## Country
|
33
|
+
|
34
|
+
country = NationalHolidays::Country.new(:gb)
|
35
|
+
|
36
|
+
puts country.code
|
37
|
+
# gb
|
38
|
+
|
39
|
+
puts country.name
|
40
|
+
# United Kingdom of Great Britain and Northern Ireland
|
41
|
+
|
42
|
+
puts country.regions.map(&:name)
|
43
|
+
# ["England", "Wales", "Scotland", "Northern Ireland"]
|
44
|
+
|
45
|
+
Country names come from https://github.com/hexorx/countries
|
46
|
+
|
47
|
+
Region names come from https://github.com/kaoru/national-holidays-config
|
48
|
+
|
49
|
+
## Region
|
50
|
+
|
51
|
+
region = NationalHolidays::Region.new(:united_states14)
|
52
|
+
|
53
|
+
puts region.code
|
54
|
+
# :united_states14
|
55
|
+
|
56
|
+
puts region.name
|
57
|
+
# Illinois
|
58
|
+
|
59
|
+
date = Date.new(2018, 1, 1)
|
60
|
+
|
61
|
+
puts region.all_holidays.count
|
62
|
+
# 374
|
63
|
+
|
64
|
+
puts region.holidays_on_or_before(date).count
|
65
|
+
# 87
|
66
|
+
puts region.holidays_before(date).count
|
67
|
+
# 86
|
68
|
+
|
69
|
+
puts region.holidays_on_or_after(date).count
|
70
|
+
# 288
|
71
|
+
puts region.holidays_after(date).count
|
72
|
+
# 287
|
73
|
+
|
74
|
+
puts region.holidays_between(date, date).count
|
75
|
+
# 1
|
76
|
+
|
77
|
+
## Holiday
|
78
|
+
|
79
|
+
holiday.names
|
80
|
+
# {
|
81
|
+
# en: "New Year's Day",
|
82
|
+
# es: "Año Nuevo"
|
83
|
+
# }
|
84
|
+
|
85
|
+
holiday.date
|
86
|
+
# Date.new(2018, 1, 1)
|
87
|
+
|
88
|
+
holiday.public_holiday?
|
89
|
+
# true
|
90
|
+
|
91
|
+
In the future we hope to also support non-public holidays, ie. days which are notable but do not mean that people get the day of work.
|
92
|
+
|
93
|
+
## Who are we?
|
94
|
+
|
95
|
+
We run [CharlieHR](https://www.charliehr.com) where knowing about public and national holidays helps us calculate time off for 1000s of companies.
|
data/Rakefile
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'countries'
|
4
|
+
|
5
|
+
class NationalHolidays
|
6
|
+
class Country
|
7
|
+
attr_reader :code, :name
|
8
|
+
|
9
|
+
def self.all
|
10
|
+
Dir.glob("#{NationalHolidays.config_directory}/*").sort.map do |country_directory|
|
11
|
+
new(File.basename(country_directory))
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(code)
|
16
|
+
@code = code.to_sym
|
17
|
+
@name = ISO3166::Country.new(code).name
|
18
|
+
end
|
19
|
+
|
20
|
+
def regions
|
21
|
+
dir = "#{NationalHolidays.config_directory}/#{code}"
|
22
|
+
|
23
|
+
raise NationalHolidays::UnknownCountryError, "Unknown country: #{code}" unless Dir.exist?(dir)
|
24
|
+
|
25
|
+
Dir.glob("#{dir}/*.yml").sort.map do |filename|
|
26
|
+
Region.new(File.basename(filename).sub(/\.yml/, ''))
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
class NationalHolidays
|
4
|
+
class Holiday
|
5
|
+
attr_reader :names, :date
|
6
|
+
|
7
|
+
def initialize(names, date, public_holiday)
|
8
|
+
@names = names.map { |k, v| [k.to_sym, v] }.to_h
|
9
|
+
@date = Date.parse(date.to_s)
|
10
|
+
@public_holiday = public_holiday
|
11
|
+
end
|
12
|
+
|
13
|
+
def public_holiday?
|
14
|
+
@public_holiday
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'national_holidays/holiday'
|
4
|
+
|
5
|
+
require 'yaml'
|
6
|
+
|
7
|
+
class NationalHolidays
|
8
|
+
class Region
|
9
|
+
attr_reader :code
|
10
|
+
|
11
|
+
def self.all
|
12
|
+
Dir.glob("#{NationalHolidays.config_directory}/*/*.yml").map do |region_filename|
|
13
|
+
new(File.basename(region_filename).sub(/\.yml/, ''))
|
14
|
+
end.sort_by(&:code)
|
15
|
+
end
|
16
|
+
|
17
|
+
def initialize(code)
|
18
|
+
@code = code.to_sym
|
19
|
+
end
|
20
|
+
|
21
|
+
def name
|
22
|
+
config.fetch('name')
|
23
|
+
end
|
24
|
+
|
25
|
+
def all_holidays
|
26
|
+
holidays
|
27
|
+
end
|
28
|
+
|
29
|
+
def holidays_on_or_before(date)
|
30
|
+
holidays(nil, date)
|
31
|
+
end
|
32
|
+
|
33
|
+
def holidays_before(date)
|
34
|
+
holidays(nil, date.prev_day)
|
35
|
+
end
|
36
|
+
|
37
|
+
def holidays_on_or_after(date)
|
38
|
+
holidays(date, nil)
|
39
|
+
end
|
40
|
+
|
41
|
+
def holidays_after(date)
|
42
|
+
holidays(date.next_day, nil)
|
43
|
+
end
|
44
|
+
|
45
|
+
def holidays_between(start_date, end_date)
|
46
|
+
holidays(start_date, end_date)
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def holidays(start_date = nil, end_date = nil)
|
52
|
+
start_date = Date.parse(start_date.to_s).to_s if start_date
|
53
|
+
end_date = Date.parse(end_date.to_s).to_s if end_date
|
54
|
+
|
55
|
+
config.fetch('years').flat_map do |_, holidays|
|
56
|
+
holidays.map do |holiday_config|
|
57
|
+
holiday_config_date = holiday_config.fetch('date')
|
58
|
+
|
59
|
+
next if start_date && start_date > holiday_config_date
|
60
|
+
next if end_date && end_date < holiday_config_date
|
61
|
+
|
62
|
+
Holiday.new(*holiday_config.values_at('names', 'date', 'public_holiday'))
|
63
|
+
end
|
64
|
+
end.compact
|
65
|
+
end
|
66
|
+
|
67
|
+
@cache = {}
|
68
|
+
class << self
|
69
|
+
attr_reader :cache
|
70
|
+
end
|
71
|
+
|
72
|
+
def config
|
73
|
+
return self.class.cache[code] if self.class.cache.key?(code)
|
74
|
+
|
75
|
+
filename = Dir.glob("#{NationalHolidays.config_directory}/*/*.yml").sort.find do |f|
|
76
|
+
File.basename(f) == "#{code}.yml"
|
77
|
+
end
|
78
|
+
|
79
|
+
raise NationalHolidays::UnknownRegionError, "Unknown region: #{code}" unless filename
|
80
|
+
|
81
|
+
self.class.cache[code] = YAML.safe_load(File.read(filename))
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require 'national_holidays'
|
5
|
+
|
6
|
+
class NationalHolidaysTest < Minitest::Test
|
7
|
+
def test_load
|
8
|
+
assert_equal true, NationalHolidays.load!
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_countries
|
12
|
+
assert_equal :ae, NationalHolidays.countries.first.code
|
13
|
+
assert_equal 'South Africa', NationalHolidays.countries.last.name
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_regions
|
17
|
+
assert_equal :angola01, NationalHolidays.regions.first.code
|
18
|
+
assert_equal 'Vietnam', NationalHolidays.regions.last.name
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_regions_to_public_holiday_count_for_year
|
22
|
+
assert_equal 8, NationalHolidays.regions_to_public_holiday_count_for_year(2017).fetch(:united_kingdom01)
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require 'national_holidays'
|
5
|
+
|
6
|
+
class NationalHolidaysCountryTest < Minitest::Test
|
7
|
+
def test_code
|
8
|
+
assert_equal :gb, NationalHolidays::Country.new(:gb).code
|
9
|
+
assert_equal :gb, NationalHolidays::Country.new('gb').code
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_name
|
13
|
+
assert_equal 'United Kingdom of Great Britain and Northern Ireland', NationalHolidays::Country.new(:gb).name
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_regions
|
17
|
+
assert_equal %i[united_kingdom01 united_kingdom02 united_kingdom03 united_kingdom04], NationalHolidays::Country.new(:gb).regions.map(&:code)
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require 'national_holidays'
|
5
|
+
|
6
|
+
class NationalHolidaysHolidayTest < Minitest::Test
|
7
|
+
def holiday
|
8
|
+
NationalHolidays::Holiday.new(
|
9
|
+
{
|
10
|
+
'en' => "New Year's Day",
|
11
|
+
'es' => 'Año Nuevo'
|
12
|
+
},
|
13
|
+
'2018-01-01',
|
14
|
+
true
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
def test_names
|
19
|
+
assert_equal "New Year's Day", holiday.names.fetch(:en)
|
20
|
+
assert_equal 'Año Nuevo', holiday.names.fetch(:es)
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_date
|
24
|
+
assert_equal Date.new(2018, 1, 1), holiday.date
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_public_holiday
|
28
|
+
assert holiday.public_holiday?
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,48 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'minitest/autorun'
|
4
|
+
require 'national_holidays'
|
5
|
+
|
6
|
+
class NationalHolidaysRegionTest < Minitest::Test
|
7
|
+
def test_code
|
8
|
+
assert_equal :united_kingdom01, NationalHolidays::Region.new(:united_kingdom01).code
|
9
|
+
assert_equal :united_kingdom01, NationalHolidays::Region.new('united_kingdom01').code
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_name
|
13
|
+
assert_equal 'England', NationalHolidays::Region.new(:united_kingdom01).name
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_all_holidays
|
17
|
+
refute_empty(NationalHolidays::Region.new(:united_kingdom01).all_holidays.select { |holiday| holiday.date == Date.new(2011, 1, 3) })
|
18
|
+
refute_empty(NationalHolidays::Region.new(:united_kingdom01).all_holidays.select { |holiday| holiday.date == Date.new(2040, 1, 2) })
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_holidays_on_or_before
|
22
|
+
refute_empty NationalHolidays::Region.new(:united_kingdom01).holidays_on_or_before(Date.new(2018, 1, 1))
|
23
|
+
assert_empty(NationalHolidays::Region.new(:united_kingdom01).holidays_on_or_before(Date.new(2018, 1, 1)).select { |holiday| holiday.date > Date.new(2018, 1, 1) })
|
24
|
+
assert_equal Date.new(2018, 1, 1), NationalHolidays::Region.new(:united_kingdom01).holidays_on_or_before(Date.new(2018, 1, 1)).last.date
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_holidays_before
|
28
|
+
refute_empty NationalHolidays::Region.new(:united_kingdom01).holidays_before(Date.new(2018, 1, 1))
|
29
|
+
assert_empty(NationalHolidays::Region.new(:united_kingdom01).holidays_before(Date.new(2018, 1, 1)).select { |holiday| holiday.date >= Date.new(2018, 1, 1) })
|
30
|
+
assert_equal Date.new(2017, 12, 26), NationalHolidays::Region.new(:united_kingdom01).holidays_before(Date.new(2018, 1, 1)).last.date
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_holidays_on_or_after
|
34
|
+
refute_empty NationalHolidays::Region.new(:united_kingdom01).holidays_on_or_after(Date.new(2018, 1, 1))
|
35
|
+
assert_empty(NationalHolidays::Region.new(:united_kingdom01).holidays_on_or_after(Date.new(2018, 1, 1)).select { |holiday| holiday.date < Date.new(2018, 1, 1) })
|
36
|
+
assert_equal Date.new(2018, 1, 1), NationalHolidays::Region.new(:united_kingdom01).holidays_on_or_after(Date.new(2018, 1, 1)).first.date
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_holidays_after
|
40
|
+
refute_empty NationalHolidays::Region.new(:united_kingdom01).holidays_after(Date.new(2018, 1, 1))
|
41
|
+
assert_empty(NationalHolidays::Region.new(:united_kingdom01).holidays_after(Date.new(2018, 1, 1)).select { |holiday| holiday.date <= Date.new(2018, 1, 1) })
|
42
|
+
assert_equal Date.new(2018, 3, 30), NationalHolidays::Region.new(:united_kingdom01).holidays_after(Date.new(2018, 1, 1)).first.date
|
43
|
+
end
|
44
|
+
|
45
|
+
def test_holidays_between
|
46
|
+
assert_equal(['Good Friday', 'Easter Monday', 'Royal Wedding Day'], NationalHolidays::Region.new(:united_kingdom01).holidays_between(Date.new(2011, 4, 1), Date.new(2011, 4, 30)).map { |holiday| holiday.names.fetch(:en) })
|
47
|
+
end
|
48
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: national_holidays
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Alex Balhatchet
|
@@ -73,8 +73,18 @@ executables: []
|
|
73
73
|
extensions: []
|
74
74
|
extra_rdoc_files: []
|
75
75
|
files:
|
76
|
+
- LICENSE.txt
|
77
|
+
- README.md
|
78
|
+
- Rakefile
|
76
79
|
- lib/national_holidays.rb
|
77
|
-
|
80
|
+
- lib/national_holidays/country.rb
|
81
|
+
- lib/national_holidays/holiday.rb
|
82
|
+
- lib/national_holidays/region.rb
|
83
|
+
- test/test_national_holidays.rb
|
84
|
+
- test/test_national_holidays_country.rb
|
85
|
+
- test/test_national_holidays_holiday.rb
|
86
|
+
- test/test_national_holidays_region.rb
|
87
|
+
homepage: https://github.com/kaoru/national-holidays-ruby
|
78
88
|
licenses:
|
79
89
|
- MIT
|
80
90
|
metadata: {}
|