diff --git a/REFERENCES b/REFERENCES index c5febf9..17dba5f 100644 --- a/REFERENCES +++ b/REFERENCES @@ -10,6 +10,7 @@ I am grateful to the following sources. * http://www.smart.net/~mmontes/ec-cal.html ==== World dates +* http://www.un.org/geninfo/faq/factsheets/FS18.HTM * http://en.wikipedia.org/wiki/List_of_holidays_by_country ==== US dates diff --git a/create_defs.rb b/create_defs.rb index d009930..bfd7a9b 100644 --- a/create_defs.rb +++ b/create_defs.rb @@ -1,47 +1,50 @@ -require 'fastercsv' +require 'yaml' -files = ['data/ca.csv', 'data/christian.csv', 'data/us.csv'] -regions = {} +module_name = 'TestModule' + +# Load the data files +files = ['data/ca.yaml'] +regions = [] #wtf rules_by_month = {} +custom_methods = {} + files.each do |file| - FasterCSV.foreach(file, {:headers => :first_row, :return_headers => false, :force_quotes => true}) do |row| - month = row['month'].to_i - rules_by_month[month] = [] unless rules_by_month[month] + def_file = YAML.load_file(file) + def_file['months'].each do |month, definitions| + rules_by_month[month] = [] + definitions.each do |definition| + rule = {} + definition.each do |key, val| + rule[key] = val + end + regions = rule['regions'].collect { |r| r.to_sym } + rule['regions'] = regions - rule = {} - row.each do |key, val| - rule[key] = val - end - regions[rule['regions'].to_sym] = true - rule['regions'] = [rule['regions']] - - # TODO: convert weeks to symbols - # added data checking - - # check if this rule already exists from another region - existed = false - rules_by_month[month].each do |ex| - if ex['name'] == rule['name'] and ex['wday'] == rule['wday'] and ex['mday'] == rule['mday'] and ex['week'] == rule['week'] - ex['regions'] << rule['regions'].flatten - existed = true + existed = false +# rules_by_month[month].each do |ex| +# if ex['name'] == rule['name'] and ex['wday'] == rule['wday'] and ex['mday'] == rule['mday'] and ex['week'] == rule['week'] +# ex['regions'] << rule['regions'].flatten +# existed = true +# end +# end + unless existed + rules_by_month[month] << rule end - end - unless existed - rules_by_month[month] << rule - end + end # /defs.each + + def_file['methods'].each do |name, code| + custom_methods[name] = code + end # /methods.each end end -out = "# This file is generated by one of the Ruby Holiday gem's Rake tasks.\n" -out << "DEFINED_REGIONS = [:" + regions.keys.join(', :') + "]\n\n" - -out << "HOLIDAYS_BY_MONTH = {\n" +# Build the definitions month_strs = [] rules_by_month.each do |month, rules| - month_str = " #{month.to_s} => [" + month_str = " #{month.to_s} => [" rule_strings = [] rules.each do |rule| str = '{' @@ -57,13 +60,56 @@ rules_by_month.each do |month, rules| str << ":name => \"#{rule['name']}\", :regions => [:" + rule['regions'].uniq.join(', :') + "]}" rule_strings << str end - month_str << rule_strings.join(",\n ") + "]" + month_str << rule_strings.join(",\n ") + "]" month_strs << month_str end month_strs.join(",\n") -out << month_strs.join(",\n") + "\n}" + +# Build the methods +method_str = '' +custom_methods.each do |key, code| + method_str << code + "\n\n" +end + + +# Build the output file +out =<<-EOC +# 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/#{module_name.downcase}' +# +# More definitions are available at http://code.dunae.ca/holidays. +# +# Definitions loaded: #{files.join(',')} +module Holidays + module #{module_name} + DEFINED_REGIONS = [:#{regions.join(', :')}] + + HOLIDAYS_BY_MONTH = { +#{month_strs.join(",\n")} + } + +#{method_str} + end +end + +Holidays.class_eval do + 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::#{module_name}::DEFINED_REGIONS) + + include Holidays::MixinModule +end +EOC File.open("test_file.rb","w") do |file| file.puts out diff --git a/data/ca.csv b/data/ca.csv deleted file mode 100644 index 08f12be..0000000 --- a/data/ca.csv +++ /dev/null @@ -1,7 +0,0 @@ -month,regions,function,mday,wday,week,name -1,ca,,1,,,"New Year's Day" -7,ca,,1,,,"Canada Day" -9,ca,,,1,1,"Labour Day" -11,ca,,11,,,"Rememberance Day" -12,ca,,25,,,"Christmas Day" -12,ca,,26,,,"Boxing Day" \ No newline at end of file diff --git a/data/ca.yaml b/data/ca.yaml new file mode 100644 index 0000000..326b94b --- /dev/null +++ b/data/ca.yaml @@ -0,0 +1,44 @@ +# Canadian holiday definitions for the Ruby Holiday gem. +# Updated 2008-11-21. +--- +months: + 0: + - name: Good Friday + regions: [ca] + function: lambda { |year| easter(year)-2 } + - name: Easter Sunday + regions: [ca] + function: lambda { |year| easter(year) } + 1: + - name: New Year's Day + regions: [ca] + mday: 1 + 7: + - name: Canada Day + regions: [ca] + mday: 1 + 9: + - name: Labour Day + week: 1 + regions: [ca] + wday: 1 + 11: + - name: Rememberance Day + regions: [ca] + mday: 11 + 12: + - name: Christmas Day + regions: [ca] + mday: 25 + - name: Boxing Day + regions: [ca] + mday: 26 +methods: + easter: | + def easter(year) + Date.civil(2008,1,1) + end + tester: | + def tester(year) + Date.civil(2005,1,1) + end \ No newline at end of file diff --git a/data/christian.csv b/data/christian.csv deleted file mode 100644 index b4c4f59..0000000 --- a/data/christian.csv +++ /dev/null @@ -1,5 +0,0 @@ -month,regions,function,mday,wday,week,name -0,christian,"lambda { |year| easter(year) }",,,,"Easter Sunday" -0,christian,"lambda { |year| easter(year)-7 }",,,,"Palm Sunday" -0,christian,"lambda { |year| easter(year)-2 }",,,,"Good Friday" -12,christian,,25,,,"Christmas Day" diff --git a/data/christian.yaml b/data/christian.yaml new file mode 100644 index 0000000..ab6778a --- /dev/null +++ b/data/christian.yaml @@ -0,0 +1,17 @@ +# Christian holiday definitions for the Ruby Holiday gem. +# Updated 2008-11-21. +--- +0: +- name: Easter Sunday + regions: [christian] + function: lambda { |year| easter(year) } +- name: Palm Sunday + regions: [christian] + function: lambda { |year| easter(year)-7 } +- name: Good Friday + regions: [christian] + function: lambda { |year| easter(year)-2 } +12: +- name: Christmas Day + regions: [christian] + mday: 25 diff --git a/data/holidays.csv b/data/holidays.csv deleted file mode 100644 index 89aba3d..0000000 --- a/data/holidays.csv +++ /dev/null @@ -1,9 +0,0 @@ -month, region, mday, wday, week, name -1, us, 1, , , 'New Year\'s Day' -1, ca, 1, , , 'New Year\'s Day' -1, au, 1, , , 'New Year\'s Day' -1, christian, 6, , , 'Epiphany' -1, us, , 1, 3, 'Martin Luther King, Jr. Day' -3, us, , 1, 3, 'George Washington\'s Birthday' -3, gr, 25, , , 'Independence Day' -4, au, 25, , , 'ANZAC Day' diff --git a/data/international.yaml b/data/international.yaml new file mode 100644 index 0000000..e69de29 diff --git a/data/mx.yaml b/data/mx.yaml new file mode 100644 index 0000000..db1e0ed --- /dev/null +++ b/data/mx.yaml @@ -0,0 +1,56 @@ +# Mexican holiday definitions for the Ruby Holiday gem. +# Updated 2008-11-21. +--- +0: +- name: Good Thursday + regions: [mx] + function: lambda { |year| easter(year)-3 } +- name: Good Friday + regions: [mx] + function: lambda { |year| easter(year)-2 } +- name: Easter Sunday + regions: [mx] + function: lambda { |year| easter(year) } +1: +- name: New Year's Day + regions: [mx] + mday: 1 +- name: New Year's Day + regions: [mx] + mday: 2 +2: +- name: D\xC3\xADa de la Constituci\xC3\xB3n + week: 1 + regions: [mx] + wday: 1 +3: +- name: Natalicio de Benito Ju\xC3\xA1rez + week: 3 + regions: [mx] + wday: 1 +5: +- name: D\xC3\xADa del Trabajo + regions: [mx] + mday: 1 +- name: La Batalla de Puebla + regions: [mx] + mday: 5 +9: +- name: D\xC3\xADa de Independencia + regions: [mx] + mday: 16 +11: +- name: Dia de Muertos + regions: [mx] + mday: 2 +- name: D\xC3\xADa de la Revoluci\xC3\xB3n + week: 3 + regions: [mx] + wday: 1 +12: +- name: Our Lady of Guadalupe's day + regions: [mx] + mday: 12 +- name: Christmas Day + regions: [mx] + mday: 25 diff --git a/data/un.yaml b/data/un.yaml new file mode 100644 index 0000000..13addd1 --- /dev/null +++ b/data/un.yaml @@ -0,0 +1,188 @@ +# United Nationas holiday definitions for the Ruby Holiday gem. +# Updated 2008-11-21. +--- +2: +- name: International Mother Language Day + regions: [un] + mday: 2 +3: +- name: United Nations Day for Women's Rights and International Peace + regions: [un] + mday: 8 +- name: International Day for the Elimination of Racial Discrimination + regions: [un] + mday: 21 +- name: Beginning of the Week of Solidarity with the Peoples Struggling against Racism and Racial Discrimination + regions: [un] + mday: 21 +- name: World Day for Water + regions: [un] + mday: 22 +- name: World Meteorological Day + regions: [un] + mday: 23 +4: +- name: World Health Day + regions: [un] + mday: 7 +- name: World Book and Copyright Day + regions: [un] + mday: 23 +5: +- name: World Press Freedom Day + regions: [un] + mday: 3 +- name: International Day of Families + regions: [un] + mday: 15 +- name: World Telecommunication Day + regions: [un] + mday: 17 +- name: World Day for Cultural Diversity for Dialogue and Development + regions: [un] + mday: 21 +- name: International Day for Biological Diversity + regions: [un] + mday: 22 +- name: Beginning of the Week of Solidarity with the Peoples of Non-Self-Governing Territories + regions: [un] + mday: 25 +- name: International Day of United Nations Peacekeepers + regions: [un] + mday: 29 +- name: World No-Tobacco Day + regions: [un] + mday: 31 +6: +- name: International Day of Innocent Children Victims of Aggression + regions: [un] + mday: 4 +- name: World Environment Day + regions: [un] + mday: 5 +- name: World Day to Combat Desertification and Drought + regions: [un] + mday: 17 +- name: World Refugee Day + regions: [un] + mday: 20 +- name: United Nations Public Service Day + regions: [un] + mday: 23 +- name: International Day against Drug Abuse and Illicit Trafficking + regions: [un] + mday: 26 +- name: International Day in Support of Victims of Torture + regions: [un] + mday: 26 +7: +- name: International Day of Cooperatives + week: 1 + regions: [un] + wday: 6 +- name: World Population Day + regions: [un] + mday: 11 +8: +- name: International Day of the World's Indigenous People + regions: [un] + mday: 9 +- name: International Youth Day + regions: [un] + mday: 12 +- name: International Day for the Remembrance of the Slave Trade and Its Abolition + regions: [un] + mday: 23 +9: +- name: International Literacy Day + regions: [un] + mday: 8 +- name: International Day for the Preservation of the Ozone Layer + regions: [un] + mday: 16 +- name: International Day of Peace + regions: [un] + mday: 21 +- name: International Day of Older Persons + regions: [un] + mday: 1 +10: +- name: World Space Week + regions: [un] + mday: 4 +- name: World Teachers' Day + regions: [un] + mday: 5 +- name: World Habitat Day + week: 1 + regions: [un] + wday: 1 +- name: International Day for Natural Disaster Reduction + week: 2 + regions: [un] + wday: 3 +- name: World Post Day + regions: [un] + mday: 9 +- name: World Mental Health Day + regions: [un] + mday: 10 +- name: World Food Day + regions: [un] + mday: 16 +- name: International Day for the Eradication of Poverty + regions: [un] + mday: 17 +- name: United Nations Day + regions: [un] + mday: 24 +- name: World Development Information Day + regions: [un] + mday: 24 +- name: Disarmament Week + regions: [un] + mday: 24 +11: +- name: International Day for Preventing the Exploitation of the Environment in War and Armed Conflict + regions: [un] + mday: 6 +- name: International Day for Tolerance + regions: [un] + mday: 16 +- name: Africa Industrialization Day + regions: [un] + mday: 20 +- name: Universal Children's Day + regions: [un] + mday: 20 +- name: World Television Day + regions: [un] + mday: 21 +- name: International Day for the Elimination of Violence against Women + regions: [un] + mday: 25 +- name: International Day of Solidarity with the Palestinian People + regions: [un] + mday: 29 +12: +- name: World AIDS Day + regions: [un] + mday: 1 +- name: International Day for the Abolition of Slavery + regions: [un] + mday: 2 +- name: International Day of Disabled Persons + regions: [un] + mday: 3 +- name: International Volunteer Day for Economic and Social Development + regions: [un] + mday: 5 +- name: International Civil Aviation Day + regions: [un] + mday: 7 +- name: Human Rights Day + regions: [un] + mday: 10 +- name: International Migrants Day + regions: [un] + mday: 18 diff --git a/data/us.csv b/data/us.csv deleted file mode 100644 index c6695ed..0000000 --- a/data/us.csv +++ /dev/null @@ -1,11 +0,0 @@ -month,regions,function,mday,wday,week,name -1,us,,1,,,"New Year's Day" -1,us,,,1,3,"Martin Luther King, Jr. Day" -3,us,,,1,3,"George Washington's Birthday" -5,us,,,1,-1,"Memorial Day" -6,us,,14,,,"Flag Day" -7,us,,4,,,"Independence Day" -9,us,,,1,1,"Labor Day" -11,us,,11,,,"Veterans Day" -11,us,,,4,4,"Thanksgiving Day" -12,us,,25,,,"Christmas Day" \ No newline at end of file diff --git a/data/us.yaml b/data/us.yaml new file mode 100644 index 0000000..d11d119 --- /dev/null +++ b/data/us.yaml @@ -0,0 +1,47 @@ +# United States holiday definitions for the Ruby Holiday gem. +# Updated 2008-11-21. +--- +1: +- name: New Year's Day + regions: [us] + mday: 1 +- name: Martin Luther King, Jr. Day + week: 3 + regions: [us] + wday: 1 +3: +- name: George Washington's Birthday + week: 3 + regions: [us] + wday: 1 +5: +- name: Memorial Day + week: -1 + regions: [us] + wday: 1 +6: +- name: Flag Day + regions: [us] + mday: 14 +7: +- name: Independence Day + regions: [us] + mday: 4 +9: +- name: Labor Day + week: 1 + regions: [us] + wday: 1 +11: +- name: Veterans Day + regions: [us] + mday: 11 +- name: Thanksgiving Day + week: 4 + regions: [us] + wday: 4 +12: +- name: Christmas Day + regions: [us] + mday: 25 + wday: \ No newline at end of file diff --git a/lib/holidays.rb b/lib/holidays.rb index d358c03..e79eb86 100644 --- a/lib/holidays.rb +++ b/lib/holidays.rb @@ -9,11 +9,12 @@ module Holidays VERSION = '0.9.0' - REGIONS = [:ca, :us, :au, :gr, :fr, :christian] - HOLIDAYS_TYPES = [:bank, :statutory, :religious, :informal] 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] + HOLIDAYS_TYPES = [:bank, :statutory, :religious, :informal] + # :wday Day of the week (0 is Sunday, 6 is Saturday) # :function Can return an integer representing mday or a Date object. @@ -52,6 +53,8 @@ module Holidays {:mday => 26, :name => 'Boxing Day', :regions => [:ca,:gr,:au]}] } + + # Get all holidays on a given date. # # [date] A Date object. @@ -145,7 +148,7 @@ private regions = [regions] unless regions.kind_of?(Array) regions = regions.collect { |r| r.to_sym } - raise UnkownRegionError unless regions.all? { |r| r == :any or REGIONS.include?(r) } + raise UnkownRegionError unless regions.all? { |r| r == :any or DEFINED_REGIONS.include?(r) } regions end diff --git a/test/fixtures/mixin_module.rb b/test/fixtures/mixin_module.rb new file mode 100644 index 0000000..c524a63 --- /dev/null +++ b/test/fixtures/mixin_module.rb @@ -0,0 +1,21 @@ +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 \ No newline at end of file diff --git a/test/test_mixins.rb b/test/test_mixins.rb new file mode 100644 index 0000000..26c7124 --- /dev/null +++ b/test/test_mixins.rb @@ -0,0 +1,15 @@ +require File.dirname(__FILE__) + '/test_helper' +require 'fixtures/mixin_module' + +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 + + end +end