Updated data/ca.yaml
Started documentation in CUSTOM DATES
This commit is contained in:
parent
99874179df
commit
1da5732747
8 changed files with 307 additions and 75 deletions
104
CUSTOM DATES
Normal file
104
CUSTOM DATES
Normal file
|
@ -0,0 +1,104 @@
|
|||
= Custom dates with the Ruby Holidays Gem
|
||||
|
||||
It's easy to add your own custom holiday definitions to the Holidays gem. In a nutshell:
|
||||
1. Build a definition file
|
||||
2. Run a <tt>rake</tt> to make a custom module
|
||||
3. <tt>require</tt> your new module
|
||||
|
||||
|
||||
== Building the YAML file
|
||||
|
||||
Definition files have two main parts: *months* and *methods*. Before you start, you may want to look some of the existing files at http://code.dunae.ca/svn/holidays/trunk/data.
|
||||
|
||||
=== Months
|
||||
|
||||
Holidays are grouped by month from 1 through 12. Each entry within a month can have several fields.
|
||||
|
||||
[<tt>name</tt>] The name of the holiday.
|
||||
[<tt>regions</tt>] One or more region codes.
|
||||
|
||||
===== Dates defined by a fixed date (e.g. January 1st)
|
||||
|
||||
[<tt>wday</tt>] Integer representing day of the month (1 through 31).
|
||||
|
||||
For example, the following holiday is on the first of the month and available in the <tt>ca</tt>, <tt>us</tt> and <tt>au</tt> regions.
|
||||
|
||||
- name: New Year's Day
|
||||
regions: [ca,us,au]
|
||||
mday: 1
|
||||
|
||||
|
||||
===== Dates defined by a week number (e.g. first Monday of a month)
|
||||
|
||||
[<tt>wday</tt>] Integer representing day of the week (0 = Sunday through 6 = Saturday).
|
||||
[<tt>week</tt>] Integer representing week number (1 = first week, 3 = third week, -1 = last week),
|
||||
|
||||
|
||||
For example, the following holiday is on the first Monday of the month and available in the <tt>ca</tt> region.
|
||||
|
||||
- name: Labour Day
|
||||
regions: [ca]
|
||||
week: 1
|
||||
wday: 1
|
||||
|
||||
|
||||
|
||||
|
||||
=== Calculating dates with methods
|
||||
|
||||
In addition to defining holidays by day or week, you can create custom methods to calculate a date.
|
||||
|
||||
For example, Canada celebrates Victoria Day, which falls on the Monday on or before May 24. So, under the <tt>methods</tt> section we could create a custom method that returns a Date object.
|
||||
|
||||
methods:
|
||||
ca_victoria_day: |
|
||||
def self.ca_victoria_day(year)
|
||||
date = Date.civil(year,5,24)
|
||||
if date.wday > 1
|
||||
date -= (date.wday - 1)
|
||||
elsif date.wday == 0
|
||||
date -= 6
|
||||
end
|
||||
date
|
||||
end
|
||||
|
||||
This would be represented in the <tt>months</tt> section as:
|
||||
|
||||
5:
|
||||
- name: Victoria Day
|
||||
regions: [ca]
|
||||
function: lambda { |year| ca_victoria_day(year) }
|
||||
|
||||
|
||||
Functions called in this manner must return either a Date object or an integer representing the day of the month.
|
||||
|
||||
|
||||
|
||||
== Building the definition module
|
||||
|
||||
Once you have your YAML definition file you need to generate a Ruby module using <tt>rake</tt>.
|
||||
|
||||
To build the module for school holidays
|
||||
|
||||
rake generate Custom custom.yaml
|
||||
|
||||
|
||||
Your module can include definitions from multiple YAML files.
|
||||
|
||||
rake generate Custom ca.yaml us.yaml mx.yaml custom.yaml
|
||||
|
||||
|
||||
Your custom module is ready to use.
|
||||
|
||||
require 'holidays'
|
||||
require 'path/to/custom'
|
||||
|
||||
Holidays.by_day(date, :your_region)
|
||||
|
||||
|
||||
|
||||
=== Sharing
|
||||
|
||||
If you've built a definition file that others might enjoy, why not share it?
|
||||
|
||||
Send any definition files to 'code' at 'dunae.ca'.
|
|
@ -100,14 +100,22 @@ module Holidays
|
|||
end
|
||||
|
||||
Holidays.class_eval do
|
||||
new_regions = []
|
||||
existing_regions = []
|
||||
if const_defined?(:DEFINED_REGIONS)
|
||||
new_regions = const_get(:DEFINED_REGIONS)
|
||||
existing_regions = const_get(:DEFINED_REGIONS)
|
||||
remove_const(:DEFINED_REGIONS)
|
||||
end
|
||||
const_set(:DEFINED_REGIONS, new_regions | Holidays::#{module_name}::DEFINED_REGIONS)
|
||||
const_set(:DEFINED_REGIONS, existing_regions | Holidays::#{module_name}::DEFINED_REGIONS)
|
||||
|
||||
include Holidays::MixinModule
|
||||
existing_defs = {}
|
||||
if const_defined?(:HOLIDAYS_BY_MONTH)
|
||||
existing_defs = const_get(:HOLIDAYS_BY_MONTH)
|
||||
remove_const(:HOLIDAYS_BY_MONTH)
|
||||
end
|
||||
#const_set(:HOLIDAYS_BY_MONTH, existing_defs.merge(Holidays::#{module_name}::HOLIDAYS_BY_MONTH))
|
||||
const_set(:HOLIDAYS_BY_MONTH, Holidays::#{module_name}::HOLIDAYS_BY_MONTH)
|
||||
|
||||
include Holidays::#{module_name}
|
||||
end
|
||||
EOC
|
||||
|
||||
|
|
94
data/ca.yaml
94
data/ca.yaml
|
@ -6,22 +6,95 @@ months:
|
|||
- name: Good Friday
|
||||
regions: [ca]
|
||||
function: lambda { |year| easter(year)-2 }
|
||||
- name: Easter Sunday
|
||||
regions: [ca]
|
||||
function: lambda { |year| easter(year) }
|
||||
- name: Easter Monday
|
||||
regions: [ca_qc]
|
||||
function: lambda { |year| easter(year)+1 }
|
||||
1:
|
||||
- name: New Year's Day
|
||||
regions: [ca]
|
||||
mday: 1
|
||||
- name: New Year's
|
||||
regions: [ca_qc]
|
||||
mday: 2
|
||||
2:
|
||||
- name: Family Day
|
||||
regions: [ca_ab, ca_on, ca_sk]
|
||||
wday: 1
|
||||
week: 3
|
||||
- name: Louis Riel Day
|
||||
regions: [ca_mb]
|
||||
wday: 1
|
||||
week: 3
|
||||
3:
|
||||
- name: St. Patrick's Day
|
||||
regions: [ca_nf]
|
||||
mday: 17
|
||||
3:
|
||||
- name: St. George's Day
|
||||
regions: [ca_nf]
|
||||
mday: 23
|
||||
5:
|
||||
- name: Victoria Day
|
||||
regions: [ca]
|
||||
function: lambda { |year| ca_victoria_day(year) }
|
||||
- name: National Patriotes Day
|
||||
regions: [ca_qc]
|
||||
function: lambda { |year| ca_victoria_day(year) }
|
||||
6:
|
||||
- name: Discovery Day
|
||||
regions: [ca_nf]
|
||||
mday: 24
|
||||
- name: Fête Nationale
|
||||
regions: [ca_qc]
|
||||
mday: 24
|
||||
- name: National Aboriginal Day
|
||||
regions: [ca_nt]
|
||||
mday: 21
|
||||
7:
|
||||
- name: Canada Day
|
||||
regions: [ca]
|
||||
mday: 1
|
||||
- name: Orangemen's Day
|
||||
regions: [ca]
|
||||
mday: 12
|
||||
- name: Nunavut Day
|
||||
regions: [ca_nu]
|
||||
mday: 9
|
||||
8:
|
||||
- name: BC Day
|
||||
week: 1
|
||||
regions: [ca_bc]
|
||||
wday: 1
|
||||
- name: Saskatchewan Day
|
||||
week: 1
|
||||
regions: [ca_sk]
|
||||
wday: 1
|
||||
- name: Heritage Day
|
||||
week: 1
|
||||
regions: [ca_ab]
|
||||
wday: 1
|
||||
- name: Natal Day
|
||||
week: 1
|
||||
regions: [ca_ns]
|
||||
wday: 1
|
||||
- name: Civic Holiday
|
||||
week: 1
|
||||
regions: [ca_on]
|
||||
wday: 1
|
||||
- name: Discovery Day
|
||||
week: 3
|
||||
regions: [ca_yk]
|
||||
wday: 1
|
||||
9:
|
||||
- name: Labour Day
|
||||
week: 1
|
||||
regions: [ca]
|
||||
wday: 1
|
||||
10:
|
||||
- name: Thanksgiving
|
||||
week: 2
|
||||
regions: [ca]
|
||||
wday: 1
|
||||
11:
|
||||
- name: Rememberance Day
|
||||
regions: [ca]
|
||||
|
@ -35,10 +108,17 @@ months:
|
|||
mday: 26
|
||||
methods:
|
||||
easter: |
|
||||
def easter(year)
|
||||
def self.easter(year)
|
||||
Date.civil(2008,1,1)
|
||||
end
|
||||
tester: |
|
||||
def tester(year)
|
||||
Date.civil(2005,1,1)
|
||||
ca_victoria_day: |
|
||||
# Monday on or before May 24
|
||||
def self.ca_victoria_day(year)
|
||||
date = Date.civil(year,5,24)
|
||||
if date.wday > 1
|
||||
date -= (date.wday - 1)
|
||||
elsif date.wday == 0
|
||||
date -= 6
|
||||
end
|
||||
date
|
||||
end
|
|
@ -12,7 +12,7 @@ module Holidays
|
|||
WEEKS = {:first => 1, :second => 2, :third => 3, :fourth => 4, :fifth => 5, :last => -1}
|
||||
MONTH_LENGTHS = [ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
|
||||
|
||||
DEFINED_REGIONS = [:ca, :us, :au, :gr, :fr, :christian]
|
||||
DEFINED_REGIONS = [:us, :au]
|
||||
HOLIDAYS_TYPES = [:bank, :statutory, :religious, :informal]
|
||||
|
||||
|
||||
|
@ -22,35 +22,8 @@ module Holidays
|
|||
# The month <tt>0</tt> is used to store events that require lambda calculations
|
||||
# and may occur in more than one month.
|
||||
HOLIDAYS_BY_MONTH = {
|
||||
0 => [{:function => lambda { |year| easter(year) }, :name => 'Easter Sunday', :regions => [:christian, :ca, :us]},
|
||||
{:function => lambda { |year| easter(year)-2 }, :name => 'Good Friday', :regions => [:christian, :ca, :us]}],
|
||||
1 => [{:mday => 1, :name => 'New Year\'s Day', :regions => [:us, :ca, :au]},
|
||||
{:mday => 1, :name => 'Australia Day', :regions => [:au]},
|
||||
{:mday => 6, :name => 'Epiphany', :regions => [:christian]},
|
||||
{:wday => 1, :week => :third, :name => 'Martin Luther King, Jr. Day', :regions => [:us]}],
|
||||
3 => [{:wday => 1, :week => :third, :name => 'George Washington\'s Birthday', :regions => [:us]},
|
||||
{:mday => 25, :name => 'Independence Day', :regions => [:gr]}],
|
||||
4 => [{:mday => 25, :name => 'ANZAC Day', :regions => [:au]}],
|
||||
5 => [{:mday => 1, :name => 'Labour Day', :regions => [:fr,:gr]},
|
||||
{:mday => 8, :name => 'Victoria 1945', :regions => [:fr]},
|
||||
{:wday => 6, :week => :third, :name => 'Armed Forces Day', :regions => [:us]},
|
||||
{:wday => 1, :week => :last, :name => 'Memorial Day', :regions => [:us]}],
|
||||
6 => [{:mday => 14, :name => 'Flag Day', :regions => [:us]},
|
||||
{:wday => 1, :week => :second, :name => 'Queen\'s Birthday', :regions => [:au]}],
|
||||
7 => [{:mday => 1, :name => 'Canada Day', :regions => [:ca]},
|
||||
{:mday => 4, :name => 'Independence Day', :regions => [:us]},
|
||||
{:mday => 14, :name => 'Ascension Day', :regions => [:fr]}],
|
||||
8 => [{:mday => 15, :name => 'Assumption of Mary', :regions => [:fr, :gr, :christian]}],
|
||||
9 => [{:wday => 1, :week => :first,:name => 'Labor Day', :regions => [:us]},
|
||||
{:wday => 1, :week => :first,:name => 'Labour Day', :regions => [:ca]}],
|
||||
10 => [{:wday => 1, :week => :second, :name => 'Columbus Day', :regions => [:us]},
|
||||
{:mday => 28, :name => 'National Day', :regions => [:gr]}],
|
||||
11 => [{:wday => 4, :week => :fourth, :name => 'Thanksgiving Day', :regions => [:us]},
|
||||
{:mday => 11, :name => 'Rememberance Day', :regions => [:ca,:au]},
|
||||
{:mday => 11, :name => 'Armistice 1918', :regions => [:fr]},
|
||||
{:mday => 1, :name => 'Touissant', :regions => [:fr]}],
|
||||
12 => [{:mday => 25, :name => 'Christmas Day', :regions => [:us,:ca,:christian,:au]},
|
||||
{:mday => 26, :name => 'Boxing Day', :regions => [:ca,:gr,:au]}]
|
||||
1 => [{:mday => 1, :name => 'New Year\'s Day', :regions => [:ca, :au]},
|
||||
{:mday => 1, :name => 'Australia Day', :regions => [:au]}]
|
||||
}
|
||||
|
||||
|
||||
|
@ -130,7 +103,16 @@ module Holidays
|
|||
hbm.each do |h|
|
||||
next unless h[:regions].any?{ |reg| regions.include?(reg) }
|
||||
|
||||
unless h[:function]
|
||||
if h[:function]
|
||||
result = h[:function].call(year)
|
||||
if result.kind_of?(Date) and result.mon == month
|
||||
holidays << h.merge({:day => result.mday})
|
||||
else #if result == mday
|
||||
holidays << h
|
||||
end
|
||||
|
||||
|
||||
else
|
||||
day = h[:mday] || Date.calculate_mday(year, month, h[:week], h[:wday])
|
||||
holidays << {:month => month, :day => day, :year => year, :name => h[:name], :regions => h[:regions]}
|
||||
end
|
||||
|
|
|
@ -21,6 +21,7 @@ Rake::RDocTask.new(:rdoc) do |rdoc|
|
|||
rdoc.title = 'Ruby Holidays Gem'
|
||||
rdoc.options << '--all' << '--inline-source' << '--line-numbers'
|
||||
rdoc.rdoc_files.include('README')
|
||||
rdoc.rdoc_files.include('CUSTOM DATES')
|
||||
rdoc.rdoc_files.include('REFERENCES')
|
||||
rdoc.rdoc_files.include('LICENSE')
|
||||
rdoc.rdoc_files.include('lib/*.rb')
|
||||
|
@ -41,7 +42,7 @@ spec = Gem::Specification.new do |s|
|
|||
s.files = FileList["{lib}/**/*"].to_a
|
||||
s.test_files = Dir.glob('test/test_*.rb')
|
||||
s.has_rdoc = true
|
||||
s.extra_rdoc_files = ['README', 'REFERENCES', 'LICENSE']
|
||||
s.extra_rdoc_files = ['README', 'CUSTOM DATES', 'REFERENCES', 'LICENSE']
|
||||
s.rdoc_options << '--all' << '--inline-source' << '--line-numbers'
|
||||
end
|
||||
|
||||
|
|
82
test/fixtures/ca.rb
vendored
Normal file
82
test/fixtures/ca.rb
vendored
Normal file
|
@ -0,0 +1,82 @@
|
|||
# This file is generated by the Ruby Holiday gem.
|
||||
#
|
||||
# To use the definitions in the file, load them right after you load the
|
||||
# Holiday gem:
|
||||
#
|
||||
# require 'holidays'
|
||||
# require 'path/to/testmodule'
|
||||
#
|
||||
# More definitions are available at http://code.dunae.ca/holidays.
|
||||
#
|
||||
# Definitions loaded: data/ca.yaml
|
||||
module Holidays
|
||||
module TestModule
|
||||
DEFINED_REGIONS = [:ca]
|
||||
|
||||
HOLIDAYS_BY_MONTH = {
|
||||
5 => [{:function => lambda { |year| ca_victoria_day(year) }, :name => "Victoria Day", :regions => [:ca]},
|
||||
{:function => lambda { |year| ca_victoria_day(year) }, :name => "National Patriotes Day", :regions => [:ca_qc]}],
|
||||
0 => [{:function => lambda { |year| easter(year)-2 }, :name => "Good Friday", :regions => [:ca]},
|
||||
{:function => lambda { |year| easter(year)+1 }, :name => "Easter Monday", :regions => [:ca_qc]}],
|
||||
11 => [{:mday => 11, :name => "Rememberance Day", :regions => [: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]}],
|
||||
1 => [{:mday => 1, :name => "New Year's Day", :regions => [:ca]},
|
||||
{:mday => 2, :name => "New Year's", :regions => [:ca_qc]}],
|
||||
12 => [{:mday => 25, :name => "Christmas Day", :regions => [:ca]},
|
||||
{:mday => 26, :name => "Boxing Day", :regions => [:ca]}],
|
||||
7 => [{:mday => 1, :name => "Canada Day", :regions => [:ca]},
|
||||
{:mday => 12, :name => "Orangemen's Day", :regions => [:ca]},
|
||||
{:mday => 9, :name => "Nunavut Day", :regions => [:ca_nu]}],
|
||||
2 => [{:wday => 1, :week => 3, :name => "Family Day", :regions => [:ca_ab, :ca_on, :ca_sk]},
|
||||
{:wday => 1, :week => 3, :name => "Louis Riel Day", :regions => [:ca_mb]}],
|
||||
8 => [{:wday => 1, :week => 1, :name => "BC Day", :regions => [:ca_bc]},
|
||||
{:wday => 1, :week => 1, :name => "Saskatchewan Day", :regions => [:ca_sk]},
|
||||
{:wday => 1, :week => 1, :name => "Heritage Day", :regions => [:ca_ab]},
|
||||
{:wday => 1, :week => 1, :name => "Natal Day", :regions => [:ca_ns]},
|
||||
{:wday => 1, :week => 1, :name => "Civic Holiday", :regions => [:ca_on]},
|
||||
{:wday => 1, :week => 3, :name => "Discovery Day", :regions => [:ca_yk]}],
|
||||
3 => [{:mday => 23, :name => "St. George's Day", :regions => [:ca_nf]}],
|
||||
9 => [{:wday => 1, :week => 1, :name => "Labour Day", :regions => [:ca]}],
|
||||
10 => [{:wday => 1, :week => 2, :name => "Thanksgiving", :regions => [:ca]}]
|
||||
}
|
||||
|
||||
def self.easter(year)
|
||||
Date.civil(2008,1,1)
|
||||
end
|
||||
|
||||
|
||||
# Monday on or before May 24
|
||||
def self.ca_victoria_day(year)
|
||||
date = Date.civil(year,5,24)
|
||||
if date.wday > 1
|
||||
date -= (date.wday - 1)
|
||||
elsif date.wday == 0
|
||||
date -= 6
|
||||
end
|
||||
date
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
Holidays.class_eval do
|
||||
existing_regions = []
|
||||
if const_defined?(:DEFINED_REGIONS)
|
||||
existing_regions = const_get(:DEFINED_REGIONS)
|
||||
remove_const(:DEFINED_REGIONS)
|
||||
end
|
||||
const_set(:DEFINED_REGIONS, existing_regions | Holidays::TestModule::DEFINED_REGIONS)
|
||||
|
||||
existing_defs = {}
|
||||
if const_defined?(:HOLIDAYS_BY_MONTH)
|
||||
existing_defs = const_get(:HOLIDAYS_BY_MONTH)
|
||||
remove_const(:HOLIDAYS_BY_MONTH)
|
||||
end
|
||||
#const_set(:HOLIDAYS_BY_MONTH, existing_defs.merge(Holidays::TestModule::HOLIDAYS_BY_MONTH))
|
||||
const_set(:HOLIDAYS_BY_MONTH, Holidays::TestModule::HOLIDAYS_BY_MONTH)
|
||||
|
||||
include Holidays::TestModule
|
||||
end
|
21
test/fixtures/mixin_module.rb
vendored
21
test/fixtures/mixin_module.rb
vendored
|
@ -1,21 +0,0 @@
|
|||
module Holidays
|
||||
module MixinModule
|
||||
DEFINED_REGIONS = [:merged_a,:merged_b]
|
||||
|
||||
def test_lambda(year)
|
||||
28
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Holidays.class_eval do
|
||||
# merge regions and holidays
|
||||
new_regions = []
|
||||
if const_defined?(:DEFINED_REGIONS)
|
||||
new_regions = const_get(:DEFINED_REGIONS)
|
||||
remove_const(:DEFINED_REGIONS)
|
||||
end
|
||||
const_set(:DEFINED_REGIONS, new_regions | Holidays::MixinModule::DEFINED_REGIONS)
|
||||
|
||||
include Holidays::MixinModule
|
||||
end
|
|
@ -1,15 +1,11 @@
|
|||
require File.dirname(__FILE__) + '/test_helper'
|
||||
require 'fixtures/mixin_module'
|
||||
require 'fixtures/ca'
|
||||
|
||||
class MixinTests < Test::Unit::TestCase
|
||||
def test_tester
|
||||
#Holidays.append_features(Holidays::MixinModule)
|
||||
puts Holidays.constants
|
||||
puts Holidays::DEFINED_REGIONS.join(',')
|
||||
assert Holidays.method_defined?(:test_lambda)
|
||||
end
|
||||
|
||||
def test_adding_region_constants
|
||||
|
||||
class CATests < Test::Unit::TestCase
|
||||
def test_ca_victoria_day
|
||||
[Date.civil(2004,5,24), Date.civil(2005,5,23), Date.civil(2006,5,22),
|
||||
Date.civil(2007,5,21), Date.civil(2008,5,19)].each do |date|
|
||||
assert_equal 'Victoria Day', Holidays.by_day(date, :ca)[0][:name]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Reference in a new issue