wombleton-holidays 0.9.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (90) hide show
  1. data/.gitignore +3 -0
  2. data/CHANGELOG +22 -0
  3. data/LICENSE +21 -0
  4. data/README.rdoc +77 -0
  5. data/REFERENCES +16 -0
  6. data/VERSION +1 -0
  7. data/data/SYNTAX +111 -0
  8. data/data/au.yaml +111 -0
  9. data/data/build_defs.rb +152 -0
  10. data/data/ca.yaml +141 -0
  11. data/data/cz.yaml +68 -0
  12. data/data/de.yaml +111 -0
  13. data/data/dk.yaml +117 -0
  14. data/data/es.yaml +161 -0
  15. data/data/fr.yaml +70 -0
  16. data/data/gb.yaml +106 -0
  17. data/data/ie.yaml +58 -0
  18. data/data/index.yaml +26 -0
  19. data/data/is.yaml +136 -0
  20. data/data/it.yaml +66 -0
  21. data/data/mx.yaml +106 -0
  22. data/data/nl.yaml +67 -0
  23. data/data/no.yaml +82 -0
  24. data/data/north_america_informal.yaml +49 -0
  25. data/data/nyse.yaml +63 -0
  26. data/data/nz.yaml +141 -0
  27. data/data/pt.yaml +85 -0
  28. data/data/se.yaml +91 -0
  29. data/data/united_nations.yaml +188 -0
  30. data/data/ups.yaml +56 -0
  31. data/data/us.yaml +81 -0
  32. data/data/za.yaml +78 -0
  33. data/holidays.gemspec +16 -0
  34. data/lib/holidays/MANIFEST +28 -0
  35. data/lib/holidays/au.rb +43 -0
  36. data/lib/holidays/ca.rb +69 -0
  37. data/lib/holidays/cz.rb +36 -0
  38. data/lib/holidays/de.rb +51 -0
  39. data/lib/holidays/dk.rb +48 -0
  40. data/lib/holidays/es.rb +53 -0
  41. data/lib/holidays/europe.rb +236 -0
  42. data/lib/holidays/fr.rb +37 -0
  43. data/lib/holidays/gb.rb +41 -0
  44. data/lib/holidays/ie.rb +33 -0
  45. data/lib/holidays/is.rb +62 -0
  46. data/lib/holidays/it.rb +36 -0
  47. data/lib/holidays/mx.rb +52 -0
  48. data/lib/holidays/nl.rb +37 -0
  49. data/lib/holidays/no.rb +40 -0
  50. data/lib/holidays/north_america.rb +108 -0
  51. data/lib/holidays/nyse.rb +33 -0
  52. data/lib/holidays/nz.rb +69 -0
  53. data/lib/holidays/pt.rb +38 -0
  54. data/lib/holidays/scandinavia.rb +115 -0
  55. data/lib/holidays/se.rb +53 -0
  56. data/lib/holidays/united_nations.rb +25 -0
  57. data/lib/holidays/ups.rb +32 -0
  58. data/lib/holidays/us.rb +49 -0
  59. data/lib/holidays/za.rb +36 -0
  60. data/lib/holidays.rb +408 -0
  61. data/rakefile.rb +103 -0
  62. data/test/defs/test_defs_au.rb +35 -0
  63. data/test/defs/test_defs_ca.rb +28 -0
  64. data/test/defs/test_defs_cz.rb +25 -0
  65. data/test/defs/test_defs_de.rb +48 -0
  66. data/test/defs/test_defs_dk.rb +29 -0
  67. data/test/defs/test_defs_es.rb +56 -0
  68. data/test/defs/test_defs_europe.rb +277 -0
  69. data/test/defs/test_defs_fr.rb +25 -0
  70. data/test/defs/test_defs_gb.rb +35 -0
  71. data/test/defs/test_defs_ie.rb +20 -0
  72. data/test/defs/test_defs_is.rb +32 -0
  73. data/test/defs/test_defs_it.rb +24 -0
  74. data/test/defs/test_defs_mx.rb +21 -0
  75. data/test/defs/test_defs_nl.rb +23 -0
  76. data/test/defs/test_defs_no.rb +28 -0
  77. data/test/defs/test_defs_north_america.rb +53 -0
  78. data/test/defs/test_defs_nyse.rb +21 -0
  79. data/test/defs/test_defs_nz.rb +21 -0
  80. data/test/defs/test_defs_pt.rb +31 -0
  81. data/test/defs/test_defs_scandinavia.rb +75 -0
  82. data/test/defs/test_defs_se.rb +32 -0
  83. data/test/defs/test_defs_ups.rb +20 -0
  84. data/test/defs/test_defs_us.rb +22 -0
  85. data/test/defs/test_defs_za.rb +24 -0
  86. data/test/test_date.rb +101 -0
  87. data/test/test_helper.rb +11 -0
  88. data/test/test_holidays.rb +117 -0
  89. data/test/test_multiple_regions.rb +20 -0
  90. metadata +172 -0
data/lib/holidays.rb ADDED
@@ -0,0 +1,408 @@
1
+ # coding: utf-8
2
+ $:.unshift File.dirname(__FILE__)
3
+
4
+ require 'digest/md5'
5
+ require 'date'
6
+
7
+ # == Region options
8
+ # Holidays can be defined as belonging to one or more regions and sub regions.
9
+ # The Holidays#on, Holidays#between, Date#holidays and Date#holiday? methods
10
+ # each allow you to specify a specific region.
11
+ #
12
+ # There are several different ways that you can specify a region:
13
+ #
14
+ # [<tt>:region</tt>]
15
+ # By region. For example, return holidays in the Canada with <tt>:ca</tt>.
16
+ # [<tt>:region_</tt>]
17
+ # By region and sub regions. For example, return holidays in Germany
18
+ # and all its sub regions with <tt>:de_</tt>.
19
+ # [<tt>:region_sub</tt>]
20
+ # By sub region. Return national holidays in Spain plus holidays in Spain's
21
+ # Valencia region with <tt>:es_v</tt>.
22
+ # [<tt>:any</tt>]
23
+ # Any region. Return holidays from any loaded region.
24
+ #
25
+ # == Other options
26
+ # [<tt>:observed</tt>] Return holidays on the day they are observed (e.g. on a Monday if they fall on a Sunday).
27
+ # [<tt>:informal</tt>] Include informal holidays (e.g. Valentine's Day)
28
+ #
29
+ # == Examples
30
+ # Return all holidays in the <tt>:ca</tt> and <tt>:us</tt> regions on the day that they are
31
+ # observed.
32
+ #
33
+ # Holidays.between(from, to, :ca, :us, :observed)
34
+ #
35
+ # Return all holidays in <tt>:ca</tt> and any <tt>:ca</tt> sub-region.
36
+ #
37
+ # Holidays.between(from, to, :ca_)
38
+ #
39
+ # Return all holidays in <tt>:ca_bc</tt> sub-region (which includes the <tt>:ca</tt>), including informal holidays.
40
+ #
41
+ # Holidays.between(from, to, :ca_bc, :informal)
42
+ module Holidays
43
+ # Exception thrown when an unknown region is requested.
44
+ class UnknownRegionError < ArgumentError; end
45
+
46
+ VERSION = '0.9.2'
47
+
48
+ @@regions = []
49
+ @@holidays_by_month = {}
50
+ @@proc_cache = {}
51
+
52
+ WEEKS = {:first => 1, :second => 2, :third => 3, :fourth => 4, :fifth => 5, :last => -1, :second_last => -2, :third_last => -3}
53
+ MONTH_LENGTHS = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]
54
+ DAY_SYMBOLS = Date::DAYNAMES.collect { |n| n.downcase.intern }
55
+
56
+ # Get all holidays on a given date.
57
+ #
58
+ # [<tt>date</tt>] A Date object.
59
+ # [<tt>:options</tt>] One or more region symbols, <tt>:informal</tt> and/or <tt>:observed</tt>.
60
+ #
61
+ # Returns an array of hashes or nil. See Holidays#between for the output
62
+ # format.
63
+ #
64
+ # Also available via Date#holidays.
65
+ def self.on(date, *options)
66
+ self.between(date, date, options)
67
+ end
68
+
69
+ # Get all holidays occuring between two dates, inclusively.
70
+ #
71
+ # Returns an array of hashes or nil.
72
+ #
73
+ # Each holiday is returned as a hash with the following fields:
74
+ # [<tt>start_date</tt>] Ruby Date object.
75
+ # [<tt>end_date</tt>] Ruby Date object.
76
+ # [<tt>options</tt>] One or more region symbols, <tt>:informal</tt> and/or <tt>:observed</tt>.
77
+ #
78
+ # ==== Example
79
+ # from = Date.civil(2008,7,1)
80
+ # to = Date.civil(2008,7,31)
81
+ #
82
+ # Holidays.between(from, to, :ca, :us)
83
+ # => [{:name => 'Canada Day', :regions => [:ca]...}
84
+ # {:name => 'Independence Day'', :regions => [:us], ...}]
85
+ def self.between(start_date, end_date, *options)
86
+ start_date = start_date.to_date if start_date.respond_to?(:to_date)
87
+ end_date = end_date.to_date if end_date.respond_to?(:to_date)
88
+ regions, observed, informal = parse_options(options)
89
+ holidays = []
90
+
91
+ dates = {}
92
+ (start_date..end_date).each do |date|
93
+ # Always include month '0' for variable-month holidays
94
+ dates[date.year] = [0] unless dates[date.year]
95
+ # TODO: test this, maybe should push then flatten
96
+ dates[date.year] << date.month unless dates[date.year].include?(date.month)
97
+ end
98
+
99
+ dates.each do |year, months|
100
+ months.each do |month|
101
+ next unless hbm = @@holidays_by_month[month]
102
+
103
+ hbm.each do |h|
104
+ next unless in_region?(regions, h[:regions])
105
+
106
+ # Skip informal holidays unless they have been requested
107
+ next if h[:type] == :informal and not informal
108
+
109
+ if h[:function]
110
+ # Holiday definition requires a calculation
111
+ result = call_proc(h[:function], year)
112
+
113
+ # Procs may return either Date or an integer representing mday
114
+ if result.kind_of?(Date)
115
+ month = result.month
116
+ mday = result.mday
117
+ else
118
+ mday = result
119
+ end
120
+ else
121
+ # Calculate the mday
122
+ mday = h[:mday] || Date.calculate_mday(year, month, h[:week], h[:wday])
123
+ end
124
+
125
+ # Silently skip bad mdays
126
+ begin
127
+ date = Date.civil(year, month, mday)
128
+ rescue; next; end
129
+
130
+ # If the :observed option is set, calculate the date when the holiday
131
+ # is observed.
132
+ if observed and h[:observed]
133
+ date = call_proc(h[:observed], date)
134
+ end
135
+
136
+ if date.between?(start_date, end_date)
137
+ holidays << {:date => date, :name => h[:name], :regions => h[:regions]}
138
+ end
139
+
140
+ end
141
+ end
142
+ end
143
+
144
+ holidays
145
+ end
146
+
147
+ # Merge a new set of definitions into the Holidays module.
148
+ #
149
+ # This method is automatically called when including holiday definition
150
+ # files.
151
+ def self.merge_defs(regions, holidays) # :nodoc:
152
+ @@regions = @@regions | regions
153
+ @@regions.uniq!
154
+
155
+ holidays.each do |month, holiday_defs|
156
+ @@holidays_by_month[month] = [] unless @@holidays_by_month[month]
157
+ holiday_defs.each do |holiday_def|
158
+
159
+ exists = false
160
+ @@holidays_by_month[month].each do |ex|
161
+ # TODO: gross.
162
+ if ex[:name] == holiday_def[:name] and ex[:wday] == holiday_def[:wday] and ex[:mday] == holiday_def[:mday] and ex[:week] == holiday_def[:week] and ex[:function_id] == holiday_def[:function_id] and ex[:type] == holiday_def[:type] and ex[:observed_id] == holiday_def[:observed_id]
163
+ # append regions
164
+ ex[:regions] << holiday_def[:regions]
165
+
166
+ # Should do this once we're done
167
+ ex[:regions].flatten!
168
+ ex[:regions].uniq!
169
+ exists = true
170
+ end
171
+ end
172
+
173
+ @@holidays_by_month[month] << holiday_def unless exists
174
+ end
175
+ end
176
+ end
177
+
178
+ # Get the date of Easter Sunday in a given year. From Easter Sunday, it is
179
+ # possible to calculate many traditional holidays in Western countries.
180
+ # Returns a Date object.
181
+ def self.easter(year)
182
+ y = year
183
+ a = y % 19
184
+ b = y / 100
185
+ c = y % 100
186
+ d = b / 4
187
+ e = b % 4
188
+ f = (b + 8) / 25
189
+ g = (b - f + 1) / 3
190
+ h = (19 * a + b - d - g + 15) % 30
191
+ i = c / 4
192
+ k = c % 4
193
+ l = (32 + 2 * e + 2 * i - h - k) % 7
194
+ m = (a + 11 * h + 22 * l) / 451
195
+ month = (h + l - 7 * m + 114) / 31
196
+ day = ((h + l - 7 * m + 114) % 31) + 1
197
+ Date.civil(year, month, day)
198
+ end
199
+
200
+ # Move date to Monday if it occurs on a Sunday.
201
+ # Used as a callback function.
202
+ def self.to_monday_if_sunday(date)
203
+ date += 1 if date.wday == 0
204
+ date
205
+ end
206
+
207
+ # Move date to Monday if it occurs on a Saturday on Sunday.
208
+ # Used as a callback function.
209
+ def self.to_monday_if_weekend(date)
210
+ date += 1 if date.wday == 0
211
+ date += 2 if date.wday == 6
212
+ date
213
+ end
214
+
215
+ # Move Boxing Day if it falls on a weekend, leaving room for Christmas.
216
+ # Used as a callback function.
217
+ def self.to_weekday_if_boxing_weekend(date)
218
+ date += 2 if date.wday == 6 or date.wday == 0
219
+ date
220
+ end
221
+
222
+ # Move date to Monday if it occurs on a Sunday or to Friday if it occurs on a
223
+ # Saturday.
224
+ # Used as a callback function.
225
+ def self.to_weekday_if_weekend(date)
226
+ date += 1 if date.wday == 0
227
+ date -= 1 if date.wday == 6
228
+ date
229
+ end
230
+
231
+ private
232
+ # Returns [(arr)regions, (bool)observed, (bool)informal]
233
+ def self.parse_options(*options) # :nodoc:
234
+ options.flatten!
235
+ observed = options.delete(:observed) ? true : false
236
+ informal = options.delete(:informal) ? true : false
237
+ regions = parse_regions(options)
238
+ return regions, observed, informal
239
+ end
240
+
241
+ # Check regions against list of supported regions and return an array of
242
+ # symbols.
243
+ #
244
+ # If a wildcard region is found (e.g. <tt>:ca_</tt>) it is expanded into all
245
+ # of its available sub regions.
246
+ def self.parse_regions(regions) # :nodoc:
247
+ regions = [regions] unless regions.kind_of?(Array)
248
+ return [:any] if regions.empty?
249
+
250
+ regions = regions.collect { |r| r.to_sym }
251
+
252
+ # Found sub region wild-card
253
+ regions.delete_if do |reg|
254
+ if reg.to_s =~ /_$/
255
+ regions << @@regions.select { |dr| dr.to_s =~ Regexp.new("^#{reg}") }
256
+ true
257
+ end
258
+ end
259
+
260
+ regions.flatten!
261
+
262
+ require "holidays/north_america" if regions.include?(:us) # special case for north_america/US cross-linking
263
+
264
+ raise UnknownRegionError unless regions.all? { |r| r == :any or @@regions.include?(r) or begin require "holidays/#{r.to_s}"; rescue LoadError; false; end }
265
+ regions
266
+ end
267
+
268
+ # Check sub regions.
269
+ #
270
+ # When request :any, all holidays should be returned.
271
+ # When requesting :ca_bc, holidays in :ca or :ca_bc should be returned.
272
+ # When requesting :ca, holidays in :ca but not its subregions should be returned.
273
+ def self.in_region?(requested, available) # :nodoc:
274
+ return true if requested.include?(:any)
275
+
276
+ # When an underscore is encountered, derive the parent regions
277
+ # symbol and include both in the requested array.
278
+ requested = requested.collect do |r|
279
+ r.to_s =~ /_/ ? [r, r.to_s.gsub(/_[\w]*$/, '').to_sym] : r
280
+ end
281
+
282
+ requested = requested.flatten.uniq
283
+
284
+ available.any? { |avail| requested.include?(avail) }
285
+ end
286
+
287
+ # Call a proc function defined in a holiday definition file.
288
+ #
289
+ # Procs are cached.
290
+ #
291
+ # ==== Benchmarks
292
+ #
293
+ # Lookup Easter Sunday, with caching, by number of iterations:
294
+ #
295
+ # user system total real
296
+ # 0001 0.000000 0.000000 0.000000 ( 0.000000)
297
+ # 0010 0.000000 0.000000 0.000000 ( 0.000000)
298
+ # 0100 0.078000 0.000000 0.078000 ( 0.078000)
299
+ # 1000 0.641000 0.000000 0.641000 ( 0.641000)
300
+ # 5000 3.172000 0.015000 3.187000 ( 3.219000)
301
+ #
302
+ # Lookup Easter Sunday, without caching, by number of iterations:
303
+ #
304
+ # user system total real
305
+ # 0001 0.000000 0.000000 0.000000 ( 0.000000)
306
+ # 0010 0.016000 0.000000 0.016000 ( 0.016000)
307
+ # 0100 0.125000 0.000000 0.125000 ( 0.125000)
308
+ # 1000 1.234000 0.000000 1.234000 ( 1.234000)
309
+ # 5000 6.094000 0.031000 6.125000 ( 6.141000)
310
+ def self.call_proc(function, year) # :nodoc:
311
+ proc_key = Digest::MD5.hexdigest("#{function.to_s}_#{year.to_s}")
312
+ @@proc_cache[proc_key] = function.call(year) unless @@proc_cache[proc_key]
313
+ @@proc_cache[proc_key]
314
+ end
315
+ end
316
+
317
+ # === Extending Ruby's Date class with the Holidays gem
318
+ # The Holidays gem automatically extends Ruby's Date class and gives you access
319
+ # to three new methods: holiday?, #holidays and #calculate_mday.
320
+ #
321
+ # ==== Examples
322
+ # Lookup Canada Day in the <tt>:ca</tt> region
323
+ # Date.civil(2008,7,1).holiday?(:ca)
324
+ # => true
325
+ #
326
+ # Lookup Canada Day in the <tt>:fr</tt> region
327
+ # Date.civil(2008,7,1).holiday?(:fr)
328
+ # => false
329
+ #
330
+ # Lookup holidays on North America in January 1.
331
+ # Date.civil(2008,1,1).holidays(:ca, :mx, :us, :informal, :observed)
332
+ # => [{:name => 'New Year\'s Day'...}]
333
+ class Date
334
+ include Holidays
335
+
336
+ # Get holidays on the current date.
337
+ #
338
+ # Returns an array of hashes or nil. See Holidays#between for options
339
+ # and the output format.
340
+ #
341
+ # Date.civil('2008-01-01').holidays(:ca_)
342
+ # => [{:name => 'New Year\'s Day',...}]
343
+ #
344
+ # Also available via Holidays#on.
345
+ def holidays(*options)
346
+ Holidays.on(self, options)
347
+ end
348
+
349
+ # Check if the current date is a holiday.
350
+ #
351
+ # Returns true or false.
352
+ #
353
+ # Date.civil('2008-01-01').holiday?(:ca)
354
+ # => true
355
+ def holiday?(*options)
356
+ holidays = self.holidays(options)
357
+ holidays && !holidays.empty?
358
+ end
359
+
360
+ # Calculate day of the month based on the week number and the day of the
361
+ # week.
362
+ #
363
+ # ==== Parameters
364
+ # [<tt>year</tt>] Integer.
365
+ # [<tt>month</tt>] Integer from 1-12.
366
+ # [<tt>week</tt>] One of <tt>:first</tt>, <tt>:second</tt>, <tt>:third</tt>,
367
+ # <tt>:fourth</tt>, <tt>:fifth</tt> or <tt>:last</tt>.
368
+ # [<tt>wday</tt>] Day of the week as an integer from 0 (Sunday) to 6
369
+ # (Saturday) or as a symbol (e.g. <tt>:monday</tt>).
370
+ #
371
+ # Returns an integer.
372
+ #
373
+ # ===== Examples
374
+ # First Monday of January, 2008:
375
+ # Date.calculate_mday(2008, 1, :first, :monday)
376
+ # => 7
377
+ #
378
+ # Third Thursday of December, 2008:
379
+ # Date.calculate_mday(2008, 12, :third, :thursday)
380
+ # => 18
381
+ #
382
+ # Last Monday of January, 2008:
383
+ # Date.calculate_mday(2008, 1, :last, 1)
384
+ # => 28
385
+ #--
386
+ # see http://www.irt.org/articles/js050/index.htm
387
+ def self.calculate_mday(year, month, week, wday)
388
+ raise ArgumentError, "Week parameter must be one of Holidays::WEEKS (provided #{week})." unless WEEKS.include?(week) or WEEKS.has_value?(week)
389
+
390
+ unless wday.kind_of?(Numeric) and wday.between?(0,6) or DAY_SYMBOLS.index(wday)
391
+ raise ArgumentError, "Wday parameter must be an integer between 0 and 6 or one of Date::DAY_SYMBOLS."
392
+ end
393
+
394
+ week = WEEKS[week] if week.kind_of?(Symbol)
395
+ wday = DAY_SYMBOLS.index(wday) if wday.kind_of?(Symbol)
396
+
397
+ # :first, :second, :third, :fourth or :fifth
398
+ if week > 0
399
+ return ((week - 1) * 7) + 1 + ((7 + wday - Date.civil(year, month,(week-1)*7 + 1).wday) % 7)
400
+ end
401
+
402
+ days = MONTH_LENGTHS[month-1]
403
+
404
+ days = 29 if month == 2 and Date.leap?(year)
405
+
406
+ return days - ((Date.civil(year, month, days).wday - wday + 7) % 7) - (7 * (week.abs - 1))
407
+ end
408
+ end
data/rakefile.rb ADDED
@@ -0,0 +1,103 @@
1
+ require 'rake'
2
+ require 'rake/testtask'
3
+ require 'rake/rdoctask'
4
+ require 'rake/gempackagetask'
5
+ require 'yaml'
6
+ require 'fileutils'
7
+ require 'lib/holidays'
8
+ require 'data/build_defs'
9
+
10
+ desc 'Run all tests'
11
+ task :test => ["test:lib", "test:defs"]
12
+
13
+ namespace :test do
14
+ desc 'Run the unit tests.'
15
+ Rake::TestTask.new(:defs) do |t|
16
+ t.libs << 'lib'
17
+ t.test_files = FileList['test/defs/test*.rb'].exclude('test_helper.rb')
18
+ t.verbose = false
19
+ end
20
+
21
+ desc 'Run the definition tests.'
22
+ Rake::TestTask.new(:lib) do |t|
23
+ t.libs << 'lib'
24
+ t.test_files = FileList['test/test*.rb'].exclude('test_helper.rb')
25
+ t.verbose = false
26
+ end
27
+ end
28
+
29
+ task :doc => ["defs:manifest", :rdoc]
30
+
31
+ desc 'Generate documentation.'
32
+ Rake::RDocTask.new(:rdoc) do |rdoc|
33
+ rdoc.rdoc_dir = 'doc'
34
+ rdoc.title = 'Ruby Holidays Gem'
35
+ rdoc.options << '--all' << '--inline-source' << '--line-numbers'
36
+ rdoc.options << '--charset' << 'utf-8'
37
+ rdoc.rdoc_files.include('README.rdoc')
38
+ rdoc.rdoc_files.include('data/SYNTAX')
39
+ rdoc.rdoc_files.include('lib/holidays/MANIFEST')
40
+ rdoc.rdoc_files.include('REFERENCES')
41
+ rdoc.rdoc_files.include('CHANGELOG')
42
+ rdoc.rdoc_files.include('LICENSE')
43
+ rdoc.rdoc_files.include('lib/*.rb')
44
+ end
45
+
46
+ desc 'Definition file tasks'
47
+ namespace :defs do
48
+ DATA_PATH = 'data'
49
+
50
+ desc 'Build holiday definition files'
51
+ task :build_all do
52
+ # load the index
53
+ def_index = YAML.load_file("#{DATA_PATH}/index.yaml")
54
+
55
+ # create a dir for the generated tests
56
+ FileUtils.mkdir_p('test/defs')
57
+
58
+ def_index['defs'].each do |region, files|
59
+ puts "Building #{region} definition module:"
60
+ files = files.collect { |f| "#{DATA_PATH}/#{f}" }
61
+ files.uniq!
62
+
63
+ module_src, test_src = parse_holiday_defs(region, files)
64
+ File.open("lib/holidays/#{region.downcase.to_s}.rb","w") do |file|
65
+ file.puts module_src
66
+ end
67
+ unless test_src.empty?
68
+ File.open("test/defs/test_defs_#{region.downcase.to_s}.rb","w") do |file|
69
+ file.puts test_src
70
+ end
71
+ end
72
+ puts "Done.\n\n"
73
+ end
74
+ end
75
+
76
+ desc 'Build the definition manifest.'
77
+ task :manifest do
78
+ File.open("lib/holidays/MANIFEST","w") do |file|
79
+ file.puts <<-EOH
80
+ ==== Regional definitions
81
+ The following definition files are included in this installation:
82
+
83
+ EOH
84
+ FileList.new('lib/holidays/*.rb').each do |str|
85
+ file.puts('* ' + str.gsub(/^lib\/|\.rb$/, ''))
86
+ end
87
+ end
88
+ end
89
+ end
90
+
91
+ begin
92
+ require 'jeweler'
93
+ Jeweler::Tasks.new do |gemspec|
94
+ gemspec.name = "wombleton-holidays"
95
+ gemspec.summary = "A collection of Ruby methods to deal with statutory and other holidays. You deserve a holiday!"
96
+ gemspec.description = "A collection of Ruby methods to deal with statutory and other holidays. You deserve a holiday!"
97
+ gemspec.email = "wombleton@gmail.com"
98
+ gemspec.homepage = "http://github.com/wombleton/holidays"
99
+ gemspec.authors = ["Alex Dunae", "Rowan Crawford"]
100
+ end
101
+ rescue LoadError
102
+ puts "Jeweler not available. Install it with: gem install jeweler"
103
+ end
@@ -0,0 +1,35 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ # This file is generated by the Ruby Holiday gem.
4
+ #
5
+ # Definitions loaded: data/au.yaml
6
+ class AuDefinitionTests < Test::Unit::TestCase # :nodoc:
7
+
8
+ def test_au
9
+ {Date.civil(2007,1,1) => 'New Year\'s Day',
10
+ Date.civil(2007,1,26) => 'Australia Day',
11
+ Date.civil(2007,4,6) => 'Good Friday',
12
+ Date.civil(2007,4,9) => 'Easter Monday',
13
+ Date.civil(2007,4,25) => 'ANZAC Day',
14
+ Date.civil(2007,12,25) => 'Christmas Day',
15
+ Date.civil(2007,12,26) => 'Boxing Day'}.each do |date, name|
16
+ assert_equal name, (Holidays.on(date, :au, :informal)[0] || {})[:name]
17
+ end
18
+
19
+ [:au_sa, :au_act, :au_nsw, :au_].each do |r|
20
+ assert_equal 'Labour Day', Date.civil(2007,10,1).holidays(r)[0][:name]
21
+ end
22
+
23
+ [:au_sa, :au_act, :au_nsw, :au_vic, :au_tas, :au_qld, :au_nt, :au_].each do |r|
24
+ assert_equal 'Queen\'s Birthday', Date.civil(2007,6,11).holidays(r)[0][:name]
25
+ end
26
+
27
+ assert_equal 'Labour Day', Date.civil(2007,3,5).holidays(:au_wa)[0][:name]
28
+ assert_equal 'Labour Day', Date.civil(2007,3,12).holidays(:au_vic)[0][:name]
29
+ assert_equal 'Labour Day', Date.civil(2007,5,7).holidays(:au_qld)[0][:name]
30
+
31
+ assert_equal 'May Day', Date.civil(2007,5,7).holidays(:au_nt)[0][:name]
32
+
33
+ assert_equal 'Eight Hours Day', Date.civil(2007,3,12).holidays(:au_tas)[0][:name]
34
+ end
35
+ end
@@ -0,0 +1,28 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ # This file is generated by the Ruby Holiday gem.
4
+ #
5
+ # Definitions loaded: data/ca.yaml, data/north_america_informal.yaml
6
+ class CaDefinitionTests < Test::Unit::TestCase # :nodoc:
7
+
8
+ def test_ca
9
+ {Date.civil(2008,1,1) => 'New Year\'s Day',
10
+ Date.civil(2008,3,21) => 'Good Friday',
11
+ Date.civil(2008,3,24) => 'Easter Monday',
12
+ Date.civil(2008,5,19) => 'Victoria Day',
13
+ Date.civil(2008,7,1) => 'Canada Day',
14
+ Date.civil(2008,9,1) => 'Labour Day',
15
+ Date.civil(2008,10,13) => 'Thanksgiving',
16
+ Date.civil(2008,11,11) => 'Rememberance Day',
17
+ Date.civil(2008,12,25) => 'Christmas Day',
18
+ Date.civil(2008,12,26) => 'Boxing Day'}.each do |date, name|
19
+ assert_equal name, (Holidays.on(date, :ca, :informal)[0] || {})[:name]
20
+ end
21
+
22
+ # Victoria Day
23
+ [Date.civil(2004,5,24), Date.civil(2005,5,23), Date.civil(2006,5,22),
24
+ Date.civil(2007,5,21), Date.civil(2008,5,19)].each do |date|
25
+ assert_equal 'Victoria Day', Holidays.on(date, :ca)[0][:name]
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,25 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ # This file is generated by the Ruby Holiday gem.
4
+ #
5
+ # Definitions loaded: data/cz.yaml
6
+ class CzDefinitionTests < Test::Unit::TestCase # :nodoc:
7
+
8
+ def test_cz
9
+ {Date.civil(2010,1,1) => 'Den obnovy samostatného českého státu',
10
+ Date.civil(2010,4,5) => 'Velikonoční pondělí',
11
+ Date.civil(2010,5,1) => 'Svátek práce',
12
+ Date.civil(2010,5,8) => 'Den vítězství',
13
+ Date.civil(2010,7,5) => 'Den slovanských věrozvěstů Cyrila a Metoděje',
14
+ Date.civil(2010,7,6) => 'Den upálení mistra Jana Husa',
15
+ Date.civil(2010,9,28) => 'Den české státnosti',
16
+ Date.civil(2010,10,28) => 'Den vzniku samostatného československého státu',
17
+ Date.civil(2010,11,17) => 'Den boje za svobodu a demokracii',
18
+ Date.civil(2010,12,24) => 'Štědrý den',
19
+ Date.civil(2010,12,25) => '1. svátek vánoční',
20
+ Date.civil(2010,12,26) => '2. svátek vánoční'}.each do |date, name|
21
+ assert_equal name, (Holidays.on(date, :cz, :informal)[0] || {})[:name]
22
+ end
23
+
24
+ end
25
+ end
@@ -0,0 +1,48 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ # This file is generated by the Ruby Holiday gem.
4
+ #
5
+ # Definitions loaded: data/de.yaml
6
+ class DeDefinitionTests < Test::Unit::TestCase # :nodoc:
7
+
8
+ def test_de
9
+ {Date.civil(2009,1,1) => 'Neujahrstag',
10
+ Date.civil(2009,4,10) => 'Karfreitag',
11
+ Date.civil(2009,4,13) => 'Ostermontag',
12
+ Date.civil(2009,5,1) => 'Tag der Arbeit',
13
+ Date.civil(2009,5,21) => 'Christi Himmelfahrt',
14
+ Date.civil(2009,6,1) => 'Pfingstmontag',
15
+ Date.civil(2009,10,3) => 'Tag der Deutschen Einheit',
16
+ Date.civil(2009,12,25) => '1. Weihnachtstag',
17
+ Date.civil(2009,12,26) => '2. Weihnachtstag'}.each do |date, name|
18
+ assert_equal name, (Holidays.on(date, :de, :informal)[0] || {})[:name]
19
+ end
20
+
21
+ [:de_bw, :de_by, :de_st, :de_].each do |r|
22
+ assert_equal 'Heilige Drei Könige', Date.civil(2009,1,6).holidays(r)[0][:name]
23
+ end
24
+
25
+ [:de_bw, :de_by, :de_he, :de_nw, :de_rp, :de_sl, :de_].each do |r|
26
+ assert_equal 'Fronleichnam', Date.civil(2009,6,11).holidays(r)[0][:name]
27
+ end
28
+
29
+ [:de_by, :de_sl, :de_].each do |r|
30
+ assert_equal 'Mariä Himmelfahrt', Date.civil(2009,8,15).holidays(r)[0][:name]
31
+ end
32
+
33
+ [:de_bb, :de_mv, :de_sn, :de_st, :de_th, :de_].each do |r|
34
+ assert_equal 'Reformationstag', Date.civil(2009,10,31).holidays(r)[0][:name]
35
+ end
36
+
37
+ [:de_bw, :de_by, :de_nw, :de_rp, :de_sl, :de_].each do |r|
38
+ assert_equal 'Allerheiligen', Date.civil(2009,11,1).holidays(r)[0][:name]
39
+ end
40
+
41
+ # Repentance Day
42
+ assert_equal 'Buß- und Bettag', Date.civil(2004,11,17).holidays(:de_sn)[0][:name]
43
+ assert_equal 'Buß- und Bettag', Date.civil(2005,11,16).holidays(:de_sn)[0][:name]
44
+ assert_equal 'Buß- und Bettag', Date.civil(2006,11,22).holidays(:de_sn)[0][:name]
45
+ assert_equal 'Buß- und Bettag', Date.civil(2009,11,18).holidays(:de_sn)[0][:name]
46
+
47
+ end
48
+ end
@@ -0,0 +1,29 @@
1
+ require File.dirname(__FILE__) + '/../test_helper'
2
+
3
+ # This file is generated by the Ruby Holiday gem.
4
+ #
5
+ # Definitions loaded: data/dk.yaml
6
+ class DkDefinitionTests < Test::Unit::TestCase # :nodoc:
7
+
8
+ def test_dk
9
+ {Date.civil(2007,1,1) => 'Nytårsdag',
10
+ Date.civil(2007,2,18) => 'Fastelavn',
11
+ Date.civil(2007,4,9) => 'Danmarks besættelse',
12
+ Date.civil(2007,4,16) => 'Dronningens fødselsdag',
13
+ Date.civil(2007,4,5) => 'Skærtorsdag',
14
+ Date.civil(2007,4,6) => 'Langfredag',
15
+ Date.civil(2007,4,8) => 'Påskedag',
16
+ Date.civil(2007,4,9) => '2. påskedag',
17
+ Date.civil(2007,5,1) => 'Arbejdernes kampdag',
18
+ Date.civil(2007,5,4) => 'Store Bededag',
19
+ Date.civil(2007,5,17) => 'Kristi Himmelfartsdag',
20
+ Date.civil(2007,5,27) => 'Pinsedag',
21
+ Date.civil(2007,5,28) => '2. Pinsedag',
22
+ Date.civil(2007,6,5) => 'Grundlovsdag',
23
+ Date.civil(2007,12,24) => 'Juleaftensdag',
24
+ Date.civil(2007,12,25) => '1. juledag',
25
+ Date.civil(2007,12,26) => '2. juledag'}.each do |date, name|
26
+ assert_equal name, (Holidays.on(date, :dk, :informal)[0] || {})[:name]
27
+ end
28
+ end
29
+ end