ice_cube 0.16.0 → 0.16.4

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +5 -5
  2. data/config/locales/de.yml +1 -1
  3. data/config/locales/en.yml +7 -46
  4. data/config/locales/es.yml +47 -83
  5. data/config/locales/fr.yml +2 -2
  6. data/config/locales/it.yml +179 -0
  7. data/config/locales/ja.yml +52 -29
  8. data/config/locales/nl.yml +133 -0
  9. data/config/locales/pt-BR.yml +178 -0
  10. data/config/locales/sv.yml +1 -1
  11. data/lib/ice_cube/i18n.rb +11 -12
  12. data/lib/ice_cube/input_alignment.rb +89 -0
  13. data/lib/ice_cube/null_i18n.rb +12 -6
  14. data/lib/ice_cube/occurrence.rb +25 -23
  15. data/lib/ice_cube/parsers/ical_parser.rb +8 -5
  16. data/lib/ice_cube/rule.rb +5 -13
  17. data/lib/ice_cube/rules/daily_rule.rb +9 -0
  18. data/lib/ice_cube/rules/hourly_rule.rb +9 -0
  19. data/lib/ice_cube/rules/minutely_rule.rb +9 -0
  20. data/lib/ice_cube/rules/monthly_rule.rb +9 -0
  21. data/lib/ice_cube/rules/secondly_rule.rb +9 -0
  22. data/lib/ice_cube/rules/weekly_rule.rb +30 -9
  23. data/lib/ice_cube/rules/yearly_rule.rb +9 -0
  24. data/lib/ice_cube/schedule.rb +30 -29
  25. data/lib/ice_cube/single_occurrence_rule.rb +4 -0
  26. data/lib/ice_cube/time_util.rb +65 -46
  27. data/lib/ice_cube/validated_rule.rb +18 -24
  28. data/lib/ice_cube/validations/count.rb +1 -2
  29. data/lib/ice_cube/validations/daily_interval.rb +5 -1
  30. data/lib/ice_cube/validations/day.rb +6 -2
  31. data/lib/ice_cube/validations/day_of_month.rb +5 -0
  32. data/lib/ice_cube/validations/day_of_week.rb +1 -1
  33. data/lib/ice_cube/validations/hour_of_day.rb +23 -0
  34. data/lib/ice_cube/validations/hourly_interval.rb +2 -0
  35. data/lib/ice_cube/validations/minute_of_hour.rb +16 -0
  36. data/lib/ice_cube/validations/minutely_interval.rb +2 -0
  37. data/lib/ice_cube/validations/month_of_year.rb +6 -1
  38. data/lib/ice_cube/validations/monthly_interval.rb +4 -1
  39. data/lib/ice_cube/validations/schedule_lock.rb +4 -0
  40. data/lib/ice_cube/validations/second_of_minute.rb +19 -3
  41. data/lib/ice_cube/validations/secondly_interval.rb +2 -0
  42. data/lib/ice_cube/validations/until.rb +1 -2
  43. data/lib/ice_cube/validations/weekly_interval.rb +0 -2
  44. data/lib/ice_cube/version.rb +1 -1
  45. data/lib/ice_cube.rb +1 -3
  46. data/spec/spec_helper.rb +32 -9
  47. metadata +10 -7
@@ -340,9 +340,9 @@ module IceCube
340
340
  IcalParser.schedule_from_ical(ical, options)
341
341
  end
342
342
 
343
- # Convert the schedule to yaml
344
- def to_yaml(*args)
345
- YAML::dump(to_hash, *args)
343
+ # Hook for YAML.dump, enables to_yaml
344
+ def encode_with(coder)
345
+ coder.represent_object nil, to_hash
346
346
  end
347
347
 
348
348
  # Load the schedule from yaml
@@ -371,6 +371,7 @@ module IceCube
371
371
  end
372
372
  data
373
373
  end
374
+ alias_method :to_h, :to_hash
374
375
 
375
376
  # Load the schedule from a hash
376
377
  def self.from_hash(original_hash, options = {})
@@ -383,9 +384,22 @@ module IceCube
383
384
  # Determine if the schedule will end
384
385
  # @return [Boolean] true if ending, false if repeating forever
385
386
  def terminating?
386
- recurrence_rules.empty? || recurrence_rules.all?(&:terminating?)
387
+ @all_recurrence_rules.all?(&:terminating?)
387
388
  end
388
389
 
390
+ def hash
391
+ [
392
+ TimeUtil.hash(start_time), duration,
393
+ *@all_recurrence_rules.map(&:hash).sort!,
394
+ *@all_exception_rules.map(&:hash).sort!
395
+ ].hash
396
+ end
397
+
398
+ def eql?(other)
399
+ self.hash == other.hash
400
+ end
401
+ alias == eql?
402
+
389
403
  def self.dump(schedule)
390
404
  return schedule if schedule.nil? || schedule == ""
391
405
  schedule.to_yaml
@@ -407,31 +421,24 @@ module IceCube
407
421
  # Find all of the occurrences for the schedule between opening_time
408
422
  # and closing_time
409
423
  # Iteration is unrolled in pairs to skip duplicate times in end of DST
410
- def enumerate_occurrences(opening_time, closing_time = nil, options = {}, &block)
424
+ def enumerate_occurrences(opening_time, closing_time = nil, options = {})
411
425
  opening_time = TimeUtil.match_zone(opening_time, start_time)
412
426
  closing_time = TimeUtil.match_zone(closing_time, start_time)
413
- opening_time += start_time.subsec - opening_time.subsec rescue 0
427
+ opening_time += TimeUtil.subsec(start_time) - TimeUtil.subsec(opening_time)
414
428
  opening_time = start_time if opening_time < start_time
415
429
  spans = options[:spans] == true && duration != 0
416
430
  Enumerator.new do |yielder|
417
431
  reset
418
- t1 = full_required? ? start_time : opening_time - (spans ? duration : 0)
432
+ t1 = full_required? ? start_time : opening_time
433
+ t1 -= duration if spans
434
+ t1 = start_time if t1 < start_time
419
435
  loop do
420
436
  break unless (t0 = next_time(t1, closing_time))
421
437
  break if closing_time && t0 > closing_time
422
438
  if (spans ? (t0.end_time > opening_time) : (t0 >= opening_time))
423
- yielder << (block_given? ? block.call(t0) : t0)
424
- end
425
- break unless (t1 = next_time(t0 + 1, closing_time))
426
- break if closing_time && t1 > closing_time
427
- if TimeUtil.same_clock?(t0, t1) && recurrence_rules.any?(&:dst_adjust?)
428
- wind_back_dst
429
- next (t1 += 1)
439
+ yielder << (block_given? ? yield(t0) : t0)
430
440
  end
431
- if (spans ? (t1.end_time > opening_time) : (t1 >= opening_time))
432
- yielder << (block_given? ? block.call(t1) : t1)
433
- end
434
- next (t1 += 1)
441
+ t1 = t0 + 1
435
442
  end
436
443
  end
437
444
  end
@@ -439,15 +446,15 @@ module IceCube
439
446
  # Get the next time after (or including) a specific time
440
447
  def next_time(time, closing_time)
441
448
  loop do
442
- min_time = recurrence_rules_with_implicit_start_occurrence.reduce(nil) do |min_time, rule|
449
+ min_time = recurrence_rules_with_implicit_start_occurrence.reduce(nil) do |best_time, rule|
443
450
  begin
444
- new_time = rule.next_time(time, start_time, min_time || closing_time)
445
- [min_time, new_time].compact.min
451
+ new_time = rule.next_time(time, start_time, best_time || closing_time)
452
+ [best_time, new_time].compact.min
446
453
  rescue StopIteration
447
- min_time
454
+ best_time
448
455
  end
449
456
  end
450
- break nil unless min_time
457
+ break unless min_time
451
458
  next (time = min_time + 1) if exception_time?(min_time)
452
459
  break Occurrence.new(min_time, min_time + duration)
453
460
  end
@@ -498,12 +505,6 @@ module IceCube
498
505
  end
499
506
  end
500
507
 
501
- def wind_back_dst
502
- recurrence_rules.each do |rule|
503
- rule.skipped_for_dst
504
- end
505
- end
506
-
507
508
  end
508
509
 
509
510
  end
@@ -23,6 +23,10 @@ module IceCube
23
23
  { :time => time }
24
24
  end
25
25
 
26
+ def full_required?
27
+ false
28
+ end
29
+
26
30
  end
27
31
 
28
32
  end
@@ -47,7 +47,7 @@ module IceCube
47
47
  time.in_time_zone(reference.time_zone)
48
48
  else
49
49
  if reference.utc?
50
- time.utc
50
+ time.getgm
51
51
  elsif reference.zone
52
52
  time.getlocal
53
53
  else
@@ -89,18 +89,27 @@ module IceCube
89
89
 
90
90
  # Serialize a time appropriate for storing
91
91
  def self.serialize_time(time)
92
- if time.respond_to?(:time_zone)
93
- {:time => time.utc, :zone => time.time_zone.name}
94
- elsif time.is_a?(Time)
95
- time
92
+ case time
93
+ when Time, Date
94
+ if time.respond_to?(:time_zone)
95
+ {:time => time.utc, :zone => time.time_zone.name}
96
+ else
97
+ time
98
+ end
99
+ when DateTime
100
+ Time.local(time.year, time.month, time.day, time.hour, time.min, time.sec)
101
+ else
102
+ raise ArgumentError, "cannot serialize #{time.inspect}, expected a Time"
96
103
  end
97
104
  end
98
105
 
99
106
  # Deserialize a time serialized with serialize_time or in ISO8601 string format
100
107
  def self.deserialize_time(time_or_hash)
101
108
  case time_or_hash
102
- when Time
109
+ when Time, Date
103
110
  time_or_hash
111
+ when DateTime
112
+ Time.local(time.year, time.month, time.day, time.hour, time.min, time.sec)
104
113
  when Hash
105
114
  hash = FlexibleHash.new(time_or_hash)
106
115
  hash[:time].in_time_zone(hash[:zone])
@@ -109,6 +118,14 @@ module IceCube
109
118
  end
110
119
  end
111
120
 
121
+ # Get a more precise equality for time objects
122
+ # Ruby provides a Time#hash method, but it fails to account for UTC
123
+ # offset (so the current date may be different) or DST rules (so the
124
+ # hour may be wrong for different schedule occurrences)
125
+ def self.hash(time)
126
+ [time, time.utc_offset, time.zone].hash
127
+ end
128
+
112
129
  # Check the deserialized time offset string against actual local time
113
130
  # offset to try and preserve the original offset for plain Ruby Time. If
114
131
  # the offset is the same as local we can assume the same original zone and
@@ -153,20 +170,13 @@ module IceCube
153
170
 
154
171
  # Convert wday number to day symbol
155
172
  def self.wday_to_sym(wday)
156
- return sym = wday if DAYS.keys.include? wday
173
+ return wday if DAYS.keys.include? wday
157
174
  DAYS.invert.fetch(wday) do |i|
158
175
  raise ArgumentError, "Expecting Integer value for weekday. " \
159
176
  "No such wday number: #{i.inspect}"
160
177
  end
161
178
  end
162
179
 
163
- # Convert a symbol to an ical day (SU, MO)
164
- def self.week_start(sym)
165
- raise ArgumentError, "Invalid day: #{str}" unless DAYS.keys.include?(sym)
166
- day = sym.to_s.upcase[0..1]
167
- day
168
- end
169
-
170
180
  # Convert weekday from base sunday to the schedule's week start.
171
181
  def self.normalize_wday(wday, week_start)
172
182
  (wday - sym_to_wday(week_start)) % 7
@@ -243,8 +253,19 @@ module IceCube
243
253
  end
244
254
  end
245
255
 
246
- def self.same_clock?(t1, t2)
247
- CLOCK_VALUES.all? { |i| t1.send(i) == t2.send(i) }
256
+ # Handle discrepancies between various time types
257
+ # - Time has subsec
258
+ # - DateTime does not
259
+ # - ActiveSupport::TimeWithZone can wrap either type, depending on version
260
+ # or if `parse` or `now`/`local` was used to build it.
261
+ def self.subsec(time)
262
+ if time.respond_to?(:subsec)
263
+ time.subsec
264
+ elsif time.respond_to?(:sec_fraction)
265
+ time.sec_fraction
266
+ else
267
+ 0.0
268
+ end
248
269
  end
249
270
 
250
271
  # A utility class for safely moving time around
@@ -252,27 +273,32 @@ module IceCube
252
273
 
253
274
  def initialize(time, dst_adjust = true)
254
275
  @dst_adjust = dst_adjust
255
- @time = time
276
+ @base = time
277
+ if dst_adjust
278
+ @time = Time.utc(time.year, time.month, time.day, time.hour, time.min, time.sec + TimeUtil.subsec(time))
279
+ else
280
+ @time = time
281
+ end
256
282
  end
257
283
 
258
- # Get the wrapper time back
284
+ # Get the wrapped time back in its original zone & format
259
285
  def to_time
260
- @time
286
+ return @time unless @dst_adjust
287
+ parts = @time.year, @time.month, @time.day, @time.hour, @time.min, @time.sec + @time.subsec
288
+ TimeUtil.build_in_zone(parts, @base)
261
289
  end
262
290
 
263
291
  # DST-safely add an interval of time to the wrapped time
264
292
  def add(type, val)
265
293
  type = :day if type == :wday
266
- adjust do
267
- @time += case type
268
- when :year then TimeUtil.days_in_n_years(@time, val) * ONE_DAY
269
- when :month then TimeUtil.days_in_n_months(@time, val) * ONE_DAY
270
- when :day then val * ONE_DAY
271
- when :hour then val * ONE_HOUR
272
- when :min then val * ONE_MINUTE
273
- when :sec then val
274
- end
275
- end
294
+ @time += case type
295
+ when :year then TimeUtil.days_in_n_years(@time, val) * ONE_DAY
296
+ when :month then TimeUtil.days_in_n_months(@time, val) * ONE_DAY
297
+ when :day then val * ONE_DAY
298
+ when :hour then val * ONE_HOUR
299
+ when :min then val * ONE_MINUTE
300
+ when :sec then val
301
+ end
276
302
  end
277
303
 
278
304
  # Clear everything below a certain type
@@ -281,23 +307,20 @@ module IceCube
281
307
  type = :day if type == :wday
282
308
  CLEAR_ORDER.each do |ptype|
283
309
  break if ptype == type
284
- adjust do
285
- send(:"clear_#{ptype}")
286
- end
310
+ send :"clear_#{ptype}"
287
311
  end
288
312
  end
289
313
 
290
- private
314
+ def hour=(value)
315
+ @time += (value * ONE_HOUR) - (@time.hour * ONE_HOUR)
316
+ end
291
317
 
292
- def adjust(&block)
293
- if @dst_adjust
294
- off = @time.utc_offset
295
- yield
296
- diff = off - @time.utc_offset
297
- @time += diff if diff != 0
298
- else
299
- yield
300
- end
318
+ def min=(value)
319
+ @time += (value * ONE_MINUTE) - (@time.min * ONE_MINUTE)
320
+ end
321
+
322
+ def sec=(value)
323
+ @time += (value) - (@time.sec)
301
324
  end
302
325
 
303
326
  def clear_sec
@@ -326,10 +349,6 @@ module IceCube
326
349
  @time += ONE_DAY
327
350
  end
328
351
 
329
- def clear_year
330
- @time
331
- end
332
-
333
352
  end
334
353
 
335
354
  end
@@ -1,18 +1,11 @@
1
+ require 'ice_cube/input_alignment'
2
+
1
3
  module IceCube
2
4
 
3
5
  class ValidatedRule < Rule
4
6
 
5
7
  include Validations::ScheduleLock
6
8
 
7
- include Validations::HourOfDay
8
- include Validations::MinuteOfHour
9
- include Validations::SecondOfMinute
10
- include Validations::DayOfMonth
11
- include Validations::DayOfWeek
12
- include Validations::Day
13
- include Validations::MonthOfYear
14
- include Validations::DayOfYear
15
-
16
9
  include Validations::Count
17
10
  include Validations::Until
18
11
 
@@ -51,15 +44,14 @@ module IceCube
51
44
  Array(@validations[base_interval_validation.type])
52
45
  end
53
46
 
54
- def base_interval_type
55
- base_interval_validation.type
56
- end
57
-
58
47
  # Compute the next time after (or including) the specified time in respect
59
48
  # to the given start time
60
49
  def next_time(time, start_time, closing_time)
61
50
  @time = time
62
- @start_time ||= realign(time, start_time)
51
+ unless @start_time
52
+ @start_time = realign(time, start_time)
53
+ @time = @start_time if @time < @start_time
54
+ end
63
55
 
64
56
  return nil unless find_acceptable_time_before(closing_time)
65
57
 
@@ -71,17 +63,13 @@ module IceCube
71
63
  start_time
72
64
  end
73
65
 
74
- def skipped_for_dst
75
- @uses -= 1 if @uses > 0
76
- end
77
-
78
- def dst_adjust?
79
- @validations[:interval].any? &:dst_adjust?
66
+ def full_required?
67
+ !occurrence_count.nil?
80
68
  end
81
69
 
82
70
  def to_s
83
71
  builder = StringBuilder.new
84
- @validations.each do |name, validations|
72
+ @validations.each_value do |validations|
85
73
  validations.each do |validation|
86
74
  validation.build_s(builder)
87
75
  end
@@ -91,7 +79,7 @@ module IceCube
91
79
 
92
80
  def to_hash
93
81
  builder = HashBuilder.new(self)
94
- @validations.each do |name, validations|
82
+ @validations.each_value do |validations|
95
83
  validations.each do |validation|
96
84
  validation.build_hash(builder)
97
85
  end
@@ -101,7 +89,7 @@ module IceCube
101
89
 
102
90
  def to_ical
103
91
  builder = IcalBuilder.new
104
- @validations.each do |name, validations|
92
+ @validations.each_value do |validations|
105
93
  validations.each do |validation|
106
94
  validation.build_ical(builder)
107
95
  end
@@ -134,7 +122,7 @@ module IceCube
134
122
 
135
123
  def normalized_interval(interval)
136
124
  int = interval.to_i
137
- raise ArgumentError, "'#{interval}' is not a valid input for interval. Please pass an integer." unless int > 0
125
+ raise ArgumentError, "'#{interval}' is not a valid input for interval. Please pass a postive integer." unless int > 0
138
126
  int
139
127
  end
140
128
 
@@ -190,6 +178,12 @@ module IceCube
190
178
  VALIDATION_ORDER & @validations.keys
191
179
  end
192
180
 
181
+ def verify_alignment(value, freq, rule_part)
182
+ InputAlignment.new(self, value, rule_part).verify(freq) do |error|
183
+ yield error
184
+ end
185
+ end
186
+
193
187
  end
194
188
 
195
189
  end
@@ -4,14 +4,13 @@ module IceCube
4
4
 
5
5
  # Value reader for limit
6
6
  def occurrence_count
7
- @count
7
+ (arr = @validations[:count]) && (val = arr[0]) && val.count
8
8
  end
9
9
 
10
10
  def count(max)
11
11
  unless max.nil? || max.is_a?(Integer)
12
12
  raise ArgumentError, "Expecting Integer or nil value for count, got #{max.inspect}"
13
13
  end
14
- @count = max
15
14
  replace_validations_for(:count, max && [Validation.new(max, self)])
16
15
  self
17
16
  end
@@ -4,7 +4,11 @@ module IceCube
4
4
 
5
5
  # Add a new interval validation
6
6
  def interval(interval)
7
- @interval = normalized_interval(interval)
7
+ interval = normalized_interval(interval)
8
+ verify_alignment(interval, :wday, :interval) { |error| raise error }
9
+ verify_alignment(interval, :day, :interval) { |error| raise error }
10
+
11
+ @interval = interval
8
12
  replace_validations_for(:interval, [Validation.new(@interval)])
9
13
  clobber_base_validations(:wday, :day)
10
14
  self
@@ -1,5 +1,3 @@
1
- require 'date'
2
-
3
1
  module IceCube
4
2
 
5
3
  module Validations::Day
@@ -12,6 +10,8 @@ module IceCube
12
10
  raise ArgumentError, "expecting Integer or Symbol value for day, got #{day.inspect}"
13
11
  end
14
12
  day = TimeUtil.sym_to_wday(day)
13
+ verify_alignment(day, :wday, :day) { |error| raise error }
14
+
15
15
  validations_for(:day) << Validation.new(day)
16
16
  end
17
17
  clobber_base_validations(:wday, :day)
@@ -27,6 +27,10 @@ module IceCube
27
27
  @day = day
28
28
  end
29
29
 
30
+ def key
31
+ :day
32
+ end
33
+
30
34
  def type
31
35
  :wday
32
36
  end
@@ -7,6 +7,7 @@ module IceCube
7
7
  unless day.is_a?(Integer)
8
8
  raise ArgumentError, "expecting Integer value for day, got #{day.inspect}"
9
9
  end
10
+ verify_alignment(day, :day, :day_of_month) { |error| raise error }
10
11
  validations_for(:day_of_month) << Validation.new(day)
11
12
  end
12
13
  clobber_base_validations(:day, :wday)
@@ -22,6 +23,10 @@ module IceCube
22
23
  @day = day
23
24
  end
24
25
 
26
+ def key
27
+ :day_of_month
28
+ end
29
+
25
30
  def type
26
31
  :day
27
32
  end
@@ -48,7 +48,7 @@ module IceCube
48
48
  builder.piece(:day_of_week) << IceCube::I18n.t(
49
49
  'ice_cube.days_of_week',
50
50
  segments: StringBuilder.nice_number(occ),
51
- day: IceCube::I18n.t('ice_cube.date.day_names')[day]
51
+ day: IceCube::I18n.t('date.day_names')[day]
52
52
  )
53
53
  end
54
54
 
@@ -8,12 +8,31 @@ module IceCube
8
8
  unless hour.is_a?(Integer)
9
9
  raise ArgumentError, "expecting Integer value for hour, got #{hour.inspect}"
10
10
  end
11
+
12
+ verify_alignment(hour, :hour, :hour_of_day) { |error| raise error }
13
+
11
14
  validations_for(:hour_of_day) << Validation.new(hour)
12
15
  end
13
16
  clobber_base_validations(:hour)
14
17
  self
15
18
  end
16
19
 
20
+ def realign(opening_time, start_time)
21
+ return super unless validations[:hour_of_day]
22
+ freq = base_interval_validation.interval
23
+
24
+ first_hour = Array(validations[:hour_of_day]).min_by(&:value)
25
+ time = TimeUtil::TimeWrapper.new(start_time, false)
26
+ if freq > 1 && base_interval_validation.type == :hour
27
+ offset = first_hour.validate(opening_time, start_time)
28
+ time.add(:hour, offset - freq)
29
+ else
30
+ time.hour = first_hour.value
31
+ end
32
+
33
+ super opening_time, time.to_time
34
+ end
35
+
17
36
  class Validation < Validations::FixedValue
18
37
 
19
38
  attr_reader :hour
@@ -23,6 +42,10 @@ module IceCube
23
42
  @hour = hour
24
43
  end
25
44
 
45
+ def key
46
+ :hour_of_day
47
+ end
48
+
26
49
  def type
27
50
  :hour
28
51
  end
@@ -3,6 +3,8 @@ module IceCube
3
3
  module Validations::HourlyInterval
4
4
 
5
5
  def interval(interval)
6
+ verify_alignment(interval, :hour, :interval) { |error| raise error }
7
+
6
8
  @interval = normalized_interval(interval)
7
9
  replace_validations_for(:interval, [Validation.new(@interval)])
8
10
  clobber_base_validations(:hour)
@@ -7,12 +7,24 @@ module IceCube
7
7
  unless minute.is_a?(Integer)
8
8
  raise ArgumentError, "expecting Integer value for minute, got #{minute.inspect}"
9
9
  end
10
+
11
+ verify_alignment(minute, :min, :minute_of_hour) { |error| raise error }
12
+
10
13
  validations_for(:minute_of_hour) << Validation.new(minute)
11
14
  end
12
15
  clobber_base_validations(:min)
13
16
  self
14
17
  end
15
18
 
19
+ def realign(opening_time, start_time)
20
+ return super unless validations[:minute_of_hour]
21
+
22
+ first_minute = validations[:minute_of_hour].min_by(&:value)
23
+ time = TimeUtil::TimeWrapper.new(start_time, false)
24
+ time.min = first_minute.value
25
+ super opening_time, time.to_time
26
+ end
27
+
16
28
  class Validation < Validations::FixedValue
17
29
 
18
30
  attr_reader :minute
@@ -22,6 +34,10 @@ module IceCube
22
34
  @minute = minute
23
35
  end
24
36
 
37
+ def key
38
+ :minute_of_hour
39
+ end
40
+
25
41
  def type
26
42
  :min
27
43
  end
@@ -3,6 +3,8 @@ module IceCube
3
3
  module Validations::MinutelyInterval
4
4
 
5
5
  def interval(interval)
6
+ verify_alignment(interval, :min, :interval) { |error| raise error }
7
+
6
8
  @interval = normalized_interval(interval)
7
9
  replace_validations_for(:interval, [Validation.new(@interval)])
8
10
  clobber_base_validations(:min)
@@ -8,6 +8,7 @@ module IceCube
8
8
  raise ArgumentError, "expecting Integer or Symbol value for month, got #{month.inspect}"
9
9
  end
10
10
  month = TimeUtil.sym_to_month(month)
11
+ verify_alignment(month, :month, :month_of_year) { |error| raise error }
11
12
  validations_for(:month_of_year) << Validation.new(month)
12
13
  end
13
14
  clobber_base_validations :month
@@ -23,6 +24,10 @@ module IceCube
23
24
  @month = month
24
25
  end
25
26
 
27
+ def key
28
+ :month_of_year
29
+ end
30
+
26
31
  def type
27
32
  :month
28
33
  end
@@ -32,7 +37,7 @@ module IceCube
32
37
  end
33
38
 
34
39
  def build_s(builder)
35
- builder.piece(:month_of_year) << IceCube::I18n.t("ice_cube.date.month_names")[month]
40
+ builder.piece(:month_of_year) << IceCube::I18n.t("date.month_names")[month]
36
41
  end
37
42
 
38
43
  def build_hash(builder)
@@ -3,7 +3,10 @@ module IceCube
3
3
  module Validations::MonthlyInterval
4
4
 
5
5
  def interval(interval)
6
- @interval = normalized_interval(interval)
6
+ interval = normalized_interval(interval)
7
+ verify_alignment(interval, :month, :interval) { |error| raise error }
8
+
9
+ @interval = interval
7
10
  replace_validations_for(:interval, [Validation.new(@interval)])
8
11
  clobber_base_validations(:month)
9
12
  self
@@ -20,6 +20,10 @@ module IceCube
20
20
  @type = type
21
21
  end
22
22
 
23
+ def key
24
+ :base
25
+ end
26
+
23
27
  def dst_adjust?
24
28
  case @type
25
29
  when :sec, :min then false