ice_cube 0.16.3 → 0.17.0
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 +5 -5
- data/config/locales/de.yml +1 -1
- data/config/locales/fr.yml +2 -2
- data/config/locales/id.yml +134 -0
- data/config/locales/it.yml +179 -0
- data/config/locales/nl.yml +133 -0
- data/config/locales/sv.yml +1 -1
- data/lib/ice_cube/builders/hash_builder.rb +1 -5
- data/lib/ice_cube/builders/ical_builder.rb +13 -15
- data/lib/ice_cube/builders/string_builder.rb +10 -16
- data/lib/ice_cube/deprecated.rb +3 -4
- data/lib/ice_cube/errors/count_exceeded.rb +0 -2
- data/lib/ice_cube/errors/until_exceeded.rb +0 -2
- data/lib/ice_cube/flexible_hash.rb +3 -7
- data/lib/ice_cube/i18n.rb +11 -23
- data/lib/ice_cube/input_alignment.rb +9 -11
- data/lib/ice_cube/null_i18n.rb +6 -6
- data/lib/ice_cube/occurrence.rb +10 -11
- data/lib/ice_cube/parsers/hash_parser.rb +3 -6
- data/lib/ice_cube/parsers/ical_parser.rb +39 -38
- data/lib/ice_cube/parsers/yaml_parser.rb +2 -4
- data/lib/ice_cube/rule.rb +7 -18
- data/lib/ice_cube/rules/daily_rule.rb +0 -4
- data/lib/ice_cube/rules/hourly_rule.rb +0 -4
- data/lib/ice_cube/rules/minutely_rule.rb +0 -4
- data/lib/ice_cube/rules/monthly_rule.rb +0 -4
- data/lib/ice_cube/rules/secondly_rule.rb +0 -4
- data/lib/ice_cube/rules/weekly_rule.rb +1 -5
- data/lib/ice_cube/rules/yearly_rule.rb +0 -4
- data/lib/ice_cube/schedule.rb +32 -40
- data/lib/ice_cube/single_occurrence_rule.rb +1 -5
- data/lib/ice_cube/time_util.rb +49 -57
- data/lib/ice_cube/validated_rule.rb +4 -10
- data/lib/ice_cube/validations/count.rb +2 -8
- data/lib/ice_cube/validations/daily_interval.rb +5 -11
- data/lib/ice_cube/validations/day.rb +7 -13
- data/lib/ice_cube/validations/day_of_month.rb +4 -10
- data/lib/ice_cube/validations/day_of_week.rb +10 -13
- data/lib/ice_cube/validations/day_of_year.rb +6 -12
- data/lib/ice_cube/validations/fixed_value.rb +9 -15
- data/lib/ice_cube/validations/hour_of_day.rb +6 -12
- data/lib/ice_cube/validations/hourly_interval.rb +3 -9
- data/lib/ice_cube/validations/lock.rb +8 -14
- data/lib/ice_cube/validations/minute_of_hour.rb +4 -10
- data/lib/ice_cube/validations/minutely_interval.rb +4 -10
- data/lib/ice_cube/validations/month_of_year.rb +2 -8
- data/lib/ice_cube/validations/monthly_interval.rb +4 -10
- data/lib/ice_cube/validations/schedule_lock.rb +0 -6
- data/lib/ice_cube/validations/second_of_minute.rb +4 -10
- data/lib/ice_cube/validations/secondly_interval.rb +2 -8
- data/lib/ice_cube/validations/until.rb +2 -8
- data/lib/ice_cube/validations/weekly_interval.rb +5 -11
- data/lib/ice_cube/validations/yearly_interval.rb +3 -9
- data/lib/ice_cube/version.rb +1 -3
- data/lib/ice_cube.rb +51 -51
- metadata +28 -12
- data/spec/spec_helper.rb +0 -79
data/lib/ice_cube/schedule.rb
CHANGED
@@ -1,9 +1,7 @@
|
|
1
|
-
require
|
1
|
+
require "yaml"
|
2
2
|
|
3
3
|
module IceCube
|
4
|
-
|
5
4
|
class Schedule
|
6
|
-
|
7
5
|
extend Deprecated
|
8
6
|
|
9
7
|
# Get the start time
|
@@ -51,7 +49,7 @@ module IceCube
|
|
51
49
|
add_recurrence_rule rule
|
52
50
|
time
|
53
51
|
end
|
54
|
-
|
52
|
+
alias_method :rtime, :add_recurrence_time
|
55
53
|
deprecated_alias :rdate, :rtime
|
56
54
|
deprecated_alias :add_recurrence_date, :add_recurrence_time
|
57
55
|
|
@@ -62,7 +60,7 @@ module IceCube
|
|
62
60
|
add_exception_rule rule
|
63
61
|
time
|
64
62
|
end
|
65
|
-
|
63
|
+
alias_method :extime, :add_exception_time
|
66
64
|
deprecated_alias :exdate, :extime
|
67
65
|
deprecated_alias :add_exception_date, :add_exception_time
|
68
66
|
|
@@ -71,7 +69,7 @@ module IceCube
|
|
71
69
|
return if rule.nil?
|
72
70
|
@all_recurrence_rules << rule unless @all_recurrence_rules.include?(rule)
|
73
71
|
end
|
74
|
-
|
72
|
+
alias_method :rrule, :add_recurrence_rule
|
75
73
|
|
76
74
|
# Remove a recurrence rule
|
77
75
|
def remove_recurrence_rule(rule)
|
@@ -84,7 +82,7 @@ module IceCube
|
|
84
82
|
return if rule.nil?
|
85
83
|
@all_exception_rules << rule unless @all_exception_rules.include?(rule)
|
86
84
|
end
|
87
|
-
|
85
|
+
alias_method :exrule, :add_exception_rule
|
88
86
|
|
89
87
|
# Remove an exception rule
|
90
88
|
def remove_exception_rule(rule)
|
@@ -96,19 +94,19 @@ module IceCube
|
|
96
94
|
def recurrence_rules
|
97
95
|
@all_recurrence_rules.reject { |r| r.is_a?(SingleOccurrenceRule) }
|
98
96
|
end
|
99
|
-
|
97
|
+
alias_method :rrules, :recurrence_rules
|
100
98
|
|
101
99
|
# Get the exception rules
|
102
100
|
def exception_rules
|
103
101
|
@all_exception_rules.reject { |r| r.is_a?(SingleOccurrenceRule) }
|
104
102
|
end
|
105
|
-
|
103
|
+
alias_method :exrules, :exception_rules
|
106
104
|
|
107
105
|
# Get the recurrence times that are on the schedule
|
108
106
|
def recurrence_times
|
109
107
|
@all_recurrence_rules.select { |r| r.is_a?(SingleOccurrenceRule) }.map(&:time)
|
110
108
|
end
|
111
|
-
|
109
|
+
alias_method :rtimes, :recurrence_times
|
112
110
|
deprecated_alias :rdates, :rtimes
|
113
111
|
deprecated_alias :recurrence_dates, :recurrence_times
|
114
112
|
|
@@ -120,7 +118,7 @@ module IceCube
|
|
120
118
|
end
|
121
119
|
time if found
|
122
120
|
end
|
123
|
-
|
121
|
+
alias_method :remove_rtime, :remove_recurrence_time
|
124
122
|
deprecated_alias :remove_recurrence_date, :remove_recurrence_time
|
125
123
|
deprecated_alias :remove_rdate, :remove_rtime
|
126
124
|
|
@@ -128,7 +126,7 @@ module IceCube
|
|
128
126
|
def exception_times
|
129
127
|
@all_exception_rules.select { |r| r.is_a?(SingleOccurrenceRule) }.map(&:time)
|
130
128
|
end
|
131
|
-
|
129
|
+
alias_method :extimes, :exception_times
|
132
130
|
deprecated_alias :exdates, :extimes
|
133
131
|
deprecated_alias :exception_dates, :exception_times
|
134
132
|
|
@@ -140,7 +138,7 @@ module IceCube
|
|
140
138
|
end
|
141
139
|
time if found
|
142
140
|
end
|
143
|
-
|
141
|
+
alias_method :remove_extime, :remove_exception_time
|
144
142
|
deprecated_alias :remove_exception_date, :remove_exception_time
|
145
143
|
deprecated_alias :remove_exdate, :remove_extime
|
146
144
|
|
@@ -162,8 +160,8 @@ module IceCube
|
|
162
160
|
end
|
163
161
|
|
164
162
|
# Iterate forever
|
165
|
-
def each_occurrence(&
|
166
|
-
enumerate_occurrences(start_time, &
|
163
|
+
def each_occurrence(&)
|
164
|
+
enumerate_occurrences(start_time, &).to_a
|
167
165
|
self
|
168
166
|
end
|
169
167
|
|
@@ -193,7 +191,7 @@ module IceCube
|
|
193
191
|
from = TimeUtil.match_zone(from, start_time) or raise ArgumentError, "Time required, got #{from.inspect}"
|
194
192
|
return [] if from <= start_time
|
195
193
|
a = enumerate_occurrences(start_time, from - 1).to_a
|
196
|
-
a.size > num ? a[-1*num,a.size] : a
|
194
|
+
(a.size > num) ? a[-1 * num, a.size] : a
|
197
195
|
end
|
198
196
|
|
199
197
|
# The remaining occurrences (same requirements as all_occurrences)
|
@@ -228,7 +226,7 @@ module IceCube
|
|
228
226
|
# occurrences at the end of the range since none of their duration
|
229
227
|
# intersects the range.
|
230
228
|
def occurring_between?(opening_time, closing_time)
|
231
|
-
occurs_between?(opening_time, closing_time, :
|
229
|
+
occurs_between?(opening_time, closing_time, spans: true)
|
232
230
|
end
|
233
231
|
|
234
232
|
# Return a boolean indicating if an occurrence falls on a certain date
|
@@ -306,7 +304,7 @@ module IceCube
|
|
306
304
|
def last(n = nil)
|
307
305
|
require_terminating_rules
|
308
306
|
occurrences = enumerate_occurrences(start_time).to_a
|
309
|
-
n.nil? ? occurrences.last : occurrences[-n
|
307
|
+
n.nil? ? occurrences.last : occurrences[-n..]
|
310
308
|
end
|
311
309
|
|
312
310
|
# String serialization
|
@@ -314,13 +312,13 @@ module IceCube
|
|
314
312
|
pieces = []
|
315
313
|
rd = recurrence_times_with_start_time - extimes
|
316
314
|
pieces.concat rd.sort.map { |t| IceCube::I18n.l(t, format: IceCube.to_s_time_format) }
|
317
|
-
pieces.concat rrules.map
|
318
|
-
pieces.concat exrules.map { |t| IceCube::I18n.t(
|
315
|
+
pieces.concat rrules.map { |t| t.to_s }
|
316
|
+
pieces.concat exrules.map { |t| IceCube::I18n.t("ice_cube.not", target: t.to_s) }
|
319
317
|
pieces.concat extimes.sort.map { |t|
|
320
318
|
target = IceCube::I18n.l(t, format: IceCube.to_s_time_format)
|
321
|
-
IceCube::I18n.t(
|
319
|
+
IceCube::I18n.t("ice_cube.not_on", target: target)
|
322
320
|
}
|
323
|
-
pieces.join(IceCube::I18n.t(
|
321
|
+
pieces.join(IceCube::I18n.t("ice_cube.pieces_connector"))
|
324
322
|
end
|
325
323
|
|
326
324
|
# Serialize this schedule to_ical
|
@@ -328,9 +326,9 @@ module IceCube
|
|
328
326
|
pieces = []
|
329
327
|
pieces << "DTSTART#{IcalBuilder.ical_format(start_time, force_utc)}"
|
330
328
|
pieces.concat recurrence_rules.map { |r| "RRULE:#{r.to_ical}" }
|
331
|
-
pieces.concat exception_rules.map
|
329
|
+
pieces.concat exception_rules.map { |r| "EXRULE:#{r.to_ical}" }
|
332
330
|
pieces.concat recurrence_times_without_start_time.map { |t| "RDATE#{IcalBuilder.ical_format(t, force_utc)}" }
|
333
|
-
pieces.concat exception_times.map
|
331
|
+
pieces.concat exception_times.map { |t| "EXDATE#{IcalBuilder.ical_format(t, force_utc)}" }
|
334
332
|
pieces << "DTEND#{IcalBuilder.ical_format(end_time, force_utc)}" if end_time
|
335
333
|
pieces.join("\n")
|
336
334
|
end
|
@@ -360,9 +358,7 @@ module IceCube
|
|
360
358
|
data[:start_date] = data[:start_time] if IceCube.compatibility <= 11
|
361
359
|
data[:end_time] = TimeUtil.serialize_time(end_time) if end_time
|
362
360
|
data[:rrules] = recurrence_rules.map(&:to_hash)
|
363
|
-
|
364
|
-
data[:exrules] = exception_rules.map(&:to_hash)
|
365
|
-
end
|
361
|
+
data[:exrules] = exception_rules.map(&:to_hash) if exception_rules.any?
|
366
362
|
data[:rtimes] = recurrence_times.map do |rt|
|
367
363
|
TimeUtil.serialize_time(rt)
|
368
364
|
end
|
@@ -396,9 +392,9 @@ module IceCube
|
|
396
392
|
end
|
397
393
|
|
398
394
|
def eql?(other)
|
399
|
-
|
395
|
+
hash == other.hash
|
400
396
|
end
|
401
|
-
|
397
|
+
alias_method :==, :eql?
|
402
398
|
|
403
399
|
def self.dump(schedule)
|
404
400
|
return schedule if schedule.nil? || schedule == ""
|
@@ -435,7 +431,7 @@ module IceCube
|
|
435
431
|
loop do
|
436
432
|
break unless (t0 = next_time(t1, closing_time))
|
437
433
|
break if closing_time && t0 > closing_time
|
438
|
-
if
|
434
|
+
if spans ? (t0.end_time > opening_time) : (t0 >= opening_time)
|
439
435
|
yielder << (block_given? ? yield(t0) : t0)
|
440
436
|
end
|
441
437
|
t1 = t0 + 1
|
@@ -447,12 +443,10 @@ module IceCube
|
|
447
443
|
def next_time(time, closing_time)
|
448
444
|
loop do
|
449
445
|
min_time = recurrence_rules_with_implicit_start_occurrence.reduce(nil) do |best_time, rule|
|
450
|
-
|
451
|
-
|
452
|
-
|
453
|
-
|
454
|
-
best_time
|
455
|
-
end
|
446
|
+
new_time = rule.next_time(time, start_time, best_time || closing_time)
|
447
|
+
[best_time, new_time].compact.min
|
448
|
+
rescue StopIteration
|
449
|
+
best_time
|
456
450
|
end
|
457
451
|
break unless min_time
|
458
452
|
next (time = min_time + 1) if exception_time?(min_time)
|
@@ -464,7 +458,7 @@ module IceCube
|
|
464
458
|
# If we have rules with counts, we need to walk from the beginning of time
|
465
459
|
def full_required?
|
466
460
|
@all_recurrence_rules.any?(&:full_required?) ||
|
467
|
-
|
461
|
+
@all_exception_rules.any?(&:full_required?)
|
468
462
|
end
|
469
463
|
|
470
464
|
# Return a boolean indicating whether or not a specific time
|
@@ -477,7 +471,7 @@ module IceCube
|
|
477
471
|
|
478
472
|
def require_terminating_rules
|
479
473
|
return true if terminating?
|
480
|
-
method_name = caller
|
474
|
+
method_name = caller(1..1).first.split(" ").last
|
481
475
|
raise ArgumentError, "All recurrence rules must specify .until or .count to use #{method_name}"
|
482
476
|
end
|
483
477
|
|
@@ -504,7 +498,5 @@ module IceCube
|
|
504
498
|
@all_recurrence_rules
|
505
499
|
end
|
506
500
|
end
|
507
|
-
|
508
501
|
end
|
509
|
-
|
510
502
|
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
module IceCube
|
2
|
-
|
3
2
|
class SingleOccurrenceRule < Rule
|
4
|
-
|
5
3
|
attr_reader :time
|
6
4
|
|
7
5
|
def initialize(time)
|
@@ -20,13 +18,11 @@ module IceCube
|
|
20
18
|
end
|
21
19
|
|
22
20
|
def to_hash
|
23
|
-
{
|
21
|
+
{time: time}
|
24
22
|
end
|
25
23
|
|
26
24
|
def full_required?
|
27
25
|
false
|
28
26
|
end
|
29
|
-
|
30
27
|
end
|
31
|
-
|
32
28
|
end
|
data/lib/ice_cube/time_util.rb
CHANGED
@@ -1,31 +1,30 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "date"
|
2
|
+
require "time"
|
3
3
|
|
4
4
|
module IceCube
|
5
5
|
module TimeUtil
|
6
|
-
|
7
6
|
extend Deprecated
|
8
7
|
|
9
8
|
DAYS = {
|
10
|
-
:
|
11
|
-
:
|
9
|
+
sunday: 0, monday: 1, tuesday: 2, wednesday: 3,
|
10
|
+
thursday: 4, friday: 5, saturday: 6
|
12
11
|
}
|
13
12
|
|
14
13
|
ICAL_DAYS = {
|
15
|
-
|
16
|
-
|
14
|
+
"SU" => :sunday, "MO" => :monday, "TU" => :tuesday, "WE" => :wednesday,
|
15
|
+
"TH" => :thursday, "FR" => :friday, "SA" => :saturday
|
17
16
|
}
|
18
17
|
|
19
18
|
MONTHS = {
|
20
|
-
:
|
21
|
-
:
|
22
|
-
:
|
19
|
+
january: 1, february: 2, march: 3, april: 4, may: 5,
|
20
|
+
june: 6, july: 7, august: 8, september: 9, october: 10,
|
21
|
+
november: 11, december: 12
|
23
22
|
}
|
24
23
|
|
25
24
|
CLOCK_VALUES = [:year, :month, :day, :hour, :min, :sec]
|
26
25
|
|
27
26
|
# Provides a Time.now without the usec, in the reference zone or utc offset
|
28
|
-
def self.now(reference=Time.now)
|
27
|
+
def self.now(reference = Time.now)
|
29
28
|
match_zone(Time.at(Time.now.to_i), reference)
|
30
29
|
end
|
31
30
|
|
@@ -42,18 +41,16 @@ module IceCube
|
|
42
41
|
end
|
43
42
|
|
44
43
|
def self.match_zone(input_time, reference)
|
45
|
-
return unless time = ensure_time(input_time, reference)
|
44
|
+
return unless (time = ensure_time(input_time, reference))
|
46
45
|
time = if reference.respond_to? :time_zone
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
end
|
56
|
-
end
|
46
|
+
time.in_time_zone(reference.time_zone)
|
47
|
+
elsif reference.utc?
|
48
|
+
time.getgm
|
49
|
+
elsif reference.zone
|
50
|
+
time.getlocal
|
51
|
+
else
|
52
|
+
time.getlocal(reference.utc_offset)
|
53
|
+
end
|
57
54
|
(Date === input_time) ? beginning_of_date(time, reference) : time
|
58
55
|
end
|
59
56
|
|
@@ -61,17 +58,15 @@ module IceCube
|
|
61
58
|
def self.ensure_time(time, reference = nil, date_eod = false)
|
62
59
|
case time
|
63
60
|
when DateTime
|
64
|
-
warn "IceCube: DateTime support is deprecated (please use Time) at: #{
|
61
|
+
warn "IceCube: DateTime support is deprecated (please use Time) at: #{caller(3..3).first}"
|
65
62
|
Time.local(time.year, time.month, time.day, time.hour, time.min, time.sec)
|
66
63
|
when Date
|
67
64
|
if date_eod
|
68
65
|
end_of_date(time, reference)
|
66
|
+
elsif reference
|
67
|
+
build_in_zone([time.year, time.month, time.day], reference)
|
69
68
|
else
|
70
|
-
|
71
|
-
build_in_zone([time.year, time.month, time.day], reference)
|
72
|
-
else
|
73
|
-
time.to_time
|
74
|
-
end
|
69
|
+
time.to_time
|
75
70
|
end
|
76
71
|
else
|
77
72
|
time
|
@@ -83,7 +78,7 @@ module IceCube
|
|
83
78
|
case date
|
84
79
|
when Date then date
|
85
80
|
else
|
86
|
-
|
81
|
+
Date.new(date.year, date.month, date.day)
|
87
82
|
end
|
88
83
|
end
|
89
84
|
|
@@ -92,7 +87,7 @@ module IceCube
|
|
92
87
|
case time
|
93
88
|
when Time, Date
|
94
89
|
if time.respond_to?(:time_zone)
|
95
|
-
{:
|
90
|
+
{time: time.utc, zone: time.time_zone.name}
|
96
91
|
else
|
97
92
|
time
|
98
93
|
end
|
@@ -133,18 +128,18 @@ module IceCube
|
|
133
128
|
# will lose the zone and not support DST.
|
134
129
|
def self.restore_deserialized_offset(time, orig_offset_str)
|
135
130
|
return time if time.respond_to?(:time_zone) ||
|
136
|
-
|
137
|
-
warn "IceCube: parsed Time from nonlocal TZ. Use ActiveSupport to fix DST at: #{
|
131
|
+
time.getlocal(orig_offset_str).utc_offset == time.utc_offset
|
132
|
+
warn "IceCube: parsed Time from nonlocal TZ. Use ActiveSupport to fix DST at: #{caller(1..1).first}"
|
138
133
|
time.localtime(orig_offset_str)
|
139
134
|
end
|
140
135
|
|
141
136
|
# Get the beginning of a date
|
142
|
-
def self.beginning_of_date(date, reference=Time.now)
|
137
|
+
def self.beginning_of_date(date, reference = Time.now)
|
143
138
|
build_in_zone([date.year, date.month, date.day, 0, 0, 0], reference)
|
144
139
|
end
|
145
140
|
|
146
141
|
# Get the end of a date
|
147
|
-
def self.end_of_date(date, reference=Time.now)
|
142
|
+
def self.end_of_date(date, reference = Time.now)
|
148
143
|
build_in_zone([date.year, date.month, date.day, 23, 59, 59], reference)
|
149
144
|
end
|
150
145
|
|
@@ -152,8 +147,8 @@ module IceCube
|
|
152
147
|
def self.sym_to_month(sym)
|
153
148
|
MONTHS.fetch(sym) do |k|
|
154
149
|
MONTHS.values.detect { |i| i.to_s == k.to_s } or
|
155
|
-
|
156
|
-
|
150
|
+
raise ArgumentError, "Expecting Integer or Symbol value for month. " \
|
151
|
+
"No such month: #{k.inspect}"
|
157
152
|
end
|
158
153
|
end
|
159
154
|
deprecated_alias :symbol_to_month, :sym_to_month
|
@@ -162,15 +157,15 @@ module IceCube
|
|
162
157
|
def self.sym_to_wday(sym)
|
163
158
|
DAYS.fetch(sym) do |k|
|
164
159
|
DAYS.values.detect { |i| i.to_s == k.to_s } or
|
165
|
-
|
166
|
-
|
160
|
+
raise ArgumentError, "Expecting Integer or Symbol value for weekday. " \
|
161
|
+
"No such weekday: #{k.inspect}"
|
167
162
|
end
|
168
163
|
end
|
169
164
|
deprecated_alias :symbol_to_day, :sym_to_wday
|
170
165
|
|
171
166
|
# Convert wday number to day symbol
|
172
167
|
def self.wday_to_sym(wday)
|
173
|
-
return wday if DAYS.
|
168
|
+
return wday if DAYS.key? wday
|
174
169
|
DAYS.invert.fetch(wday) do |i|
|
175
170
|
raise ArgumentError, "Expecting Integer value for weekday. " \
|
176
171
|
"No such wday number: #{i.inspect}"
|
@@ -270,14 +265,13 @@ module IceCube
|
|
270
265
|
|
271
266
|
# A utility class for safely moving time around
|
272
267
|
class TimeWrapper
|
273
|
-
|
274
268
|
def initialize(time, dst_adjust = true)
|
275
269
|
@dst_adjust = dst_adjust
|
276
270
|
@base = time
|
277
|
-
if dst_adjust
|
278
|
-
|
271
|
+
@time = if dst_adjust
|
272
|
+
Time.utc(time.year, time.month, time.day, time.hour, time.min, time.sec + TimeUtil.subsec(time))
|
279
273
|
else
|
280
|
-
|
274
|
+
time
|
281
275
|
end
|
282
276
|
end
|
283
277
|
|
@@ -292,13 +286,13 @@ module IceCube
|
|
292
286
|
def add(type, val)
|
293
287
|
type = :day if type == :wday
|
294
288
|
@time += case type
|
295
|
-
|
296
|
-
|
297
|
-
|
298
|
-
|
299
|
-
|
300
|
-
|
301
|
-
|
289
|
+
when :year then TimeUtil.days_in_n_years(@time, val) * ONE_DAY
|
290
|
+
when :month then TimeUtil.days_in_n_months(@time, val) * ONE_DAY
|
291
|
+
when :day then val * ONE_DAY
|
292
|
+
when :hour then val * ONE_HOUR
|
293
|
+
when :min then val * ONE_MINUTE
|
294
|
+
when :sec then val
|
295
|
+
end
|
302
296
|
end
|
303
297
|
|
304
298
|
# Clear everything below a certain type
|
@@ -320,24 +314,24 @@ module IceCube
|
|
320
314
|
end
|
321
315
|
|
322
316
|
def sec=(value)
|
323
|
-
@time +=
|
317
|
+
@time += value - @time.sec
|
324
318
|
end
|
325
319
|
|
326
320
|
def clear_sec
|
327
|
-
@time.sec > 0 ? @time -= @time.sec : @time
|
321
|
+
(@time.sec > 0) ? @time -= @time.sec : @time
|
328
322
|
end
|
329
323
|
|
330
324
|
def clear_min
|
331
|
-
@time.min > 0 ? @time -= (@time.min * ONE_MINUTE) : @time
|
325
|
+
(@time.min > 0) ? @time -= (@time.min * ONE_MINUTE) : @time
|
332
326
|
end
|
333
327
|
|
334
328
|
def clear_hour
|
335
|
-
@time.hour > 0 ? @time -= (@time.hour * ONE_HOUR) : @time
|
329
|
+
(@time.hour > 0) ? @time -= (@time.hour * ONE_HOUR) : @time
|
336
330
|
end
|
337
331
|
|
338
332
|
# Move to the first of the month, 0 hours
|
339
333
|
def clear_day
|
340
|
-
@time.day > 1 ? @time -= (@time.day - 1) * ONE_DAY : @time
|
334
|
+
(@time.day > 1) ? @time -= (@time.day - 1) * ONE_DAY : @time
|
341
335
|
end
|
342
336
|
|
343
337
|
# Clear to january 1st
|
@@ -348,8 +342,6 @@ module IceCube
|
|
348
342
|
end
|
349
343
|
@time += ONE_DAY
|
350
344
|
end
|
351
|
-
|
352
345
|
end
|
353
|
-
|
354
346
|
end
|
355
347
|
end
|
@@ -1,9 +1,7 @@
|
|
1
|
-
require
|
1
|
+
require "ice_cube/input_alignment"
|
2
2
|
|
3
3
|
module IceCube
|
4
|
-
|
5
4
|
class ValidatedRule < Rule
|
6
|
-
|
7
5
|
include Validations::ScheduleLock
|
8
6
|
|
9
7
|
include Validations::Count
|
@@ -26,7 +24,7 @@ module IceCube
|
|
26
24
|
attr_reader :validations
|
27
25
|
|
28
26
|
def initialize(interval = 1)
|
29
|
-
@validations =
|
27
|
+
@validations = {}
|
30
28
|
end
|
31
29
|
|
32
30
|
# Reset the uses on the rule to 0
|
@@ -48,10 +46,8 @@ module IceCube
|
|
48
46
|
# to the given start time
|
49
47
|
def next_time(time, start_time, closing_time)
|
50
48
|
@time = time
|
51
|
-
|
52
|
-
|
53
|
-
@time = @start_time if @time < @start_time
|
54
|
-
end
|
49
|
+
@start_time ||= realign(time, start_time)
|
50
|
+
@time = @start_time if @time < @start_time
|
55
51
|
|
56
52
|
return nil unless find_acceptable_time_before(closing_time)
|
57
53
|
|
@@ -183,7 +179,5 @@ module IceCube
|
|
183
179
|
yield error
|
184
180
|
end
|
185
181
|
end
|
186
|
-
|
187
182
|
end
|
188
|
-
|
189
183
|
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
module IceCube
|
2
|
-
|
3
2
|
module Validations::Count
|
4
|
-
|
5
3
|
# Value reader for limit
|
6
4
|
def occurrence_count
|
7
5
|
(arr = @validations[:count]) && (val = arr[0]) && val.count
|
@@ -16,7 +14,6 @@ module IceCube
|
|
16
14
|
end
|
17
15
|
|
18
16
|
class Validation
|
19
|
-
|
20
17
|
attr_reader :rule, :count
|
21
18
|
|
22
19
|
def initialize(count, rule)
|
@@ -45,16 +42,13 @@ module IceCube
|
|
45
42
|
end
|
46
43
|
|
47
44
|
def build_ical(builder)
|
48
|
-
builder[
|
45
|
+
builder["COUNT"] << count
|
49
46
|
end
|
50
47
|
|
51
48
|
StringBuilder.register_formatter(:count) do |segments|
|
52
49
|
count = segments.first
|
53
|
-
IceCube::I18n.t(
|
50
|
+
IceCube::I18n.t("ice_cube.times", count: count)
|
54
51
|
end
|
55
|
-
|
56
52
|
end
|
57
|
-
|
58
53
|
end
|
59
|
-
|
60
54
|
end
|
@@ -1,12 +1,10 @@
|
|
1
1
|
module IceCube
|
2
|
-
|
3
2
|
module Validations::DailyInterval
|
4
|
-
|
5
3
|
# Add a new interval validation
|
6
4
|
def interval(interval)
|
7
5
|
interval = normalized_interval(interval)
|
8
6
|
verify_alignment(interval, :wday, :interval) { |error| raise error }
|
9
|
-
verify_alignment(interval, :day, :interval)
|
7
|
+
verify_alignment(interval, :day, :interval) { |error| raise error }
|
10
8
|
|
11
9
|
@interval = interval
|
12
10
|
replace_validations_for(:interval, [Validation.new(@interval)])
|
@@ -15,7 +13,6 @@ module IceCube
|
|
15
13
|
end
|
16
14
|
|
17
15
|
class Validation
|
18
|
-
|
19
16
|
attr_reader :interval
|
20
17
|
|
21
18
|
def initialize(interval)
|
@@ -33,13 +30,13 @@ module IceCube
|
|
33
30
|
def validate(step_time, start_time)
|
34
31
|
t0, t1 = start_time, step_time
|
35
32
|
days = Date.new(t1.year, t1.month, t1.day) -
|
36
|
-
|
33
|
+
Date.new(t0.year, t0.month, t0.day)
|
37
34
|
offset = (days % interval).nonzero?
|
38
35
|
interval - offset if offset
|
39
36
|
end
|
40
37
|
|
41
38
|
def build_s(builder)
|
42
|
-
builder.base = IceCube::I18n.t(
|
39
|
+
builder.base = IceCube::I18n.t("ice_cube.each_day", count: interval)
|
43
40
|
end
|
44
41
|
|
45
42
|
def build_hash(builder)
|
@@ -47,12 +44,9 @@ module IceCube
|
|
47
44
|
end
|
48
45
|
|
49
46
|
def build_ical(builder)
|
50
|
-
builder[
|
51
|
-
builder[
|
47
|
+
builder["FREQ"] << "DAILY"
|
48
|
+
builder["INTERVAL"] << interval unless interval == 1
|
52
49
|
end
|
53
|
-
|
54
50
|
end
|
55
|
-
|
56
51
|
end
|
57
|
-
|
58
52
|
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
module IceCube
|
2
|
-
|
3
2
|
module Validations::Day
|
4
|
-
|
5
3
|
def day(*days)
|
6
4
|
days = days.flatten
|
7
5
|
return self if days.empty?
|
@@ -19,9 +17,8 @@ module IceCube
|
|
19
17
|
end
|
20
18
|
|
21
19
|
class Validation < Validations::FixedValue
|
22
|
-
|
23
20
|
attr_reader :day
|
24
|
-
|
21
|
+
alias_method :value, :day
|
25
22
|
|
26
23
|
def initialize(day)
|
27
24
|
@day = day
|
@@ -50,8 +47,8 @@ module IceCube
|
|
50
47
|
def build_ical(builder)
|
51
48
|
ical_day = IcalBuilder.fixnum_to_ical_day(day)
|
52
49
|
# Only add if there aren't others from day_of_week that override
|
53
|
-
if builder[
|
54
|
-
builder[
|
50
|
+
if builder["BYDAY"].none? { |b| b.end_with?(ical_day) }
|
51
|
+
builder["BYDAY"] << ical_day
|
55
52
|
end
|
56
53
|
end
|
57
54
|
|
@@ -60,18 +57,15 @@ module IceCube
|
|
60
57
|
validation_days.sort!
|
61
58
|
# pick the right shortening, if applicable
|
62
59
|
if validation_days == [0, 6]
|
63
|
-
IceCube::I18n.t(
|
60
|
+
IceCube::I18n.t("ice_cube.on_weekends")
|
64
61
|
elsif validation_days == (1..5).to_a
|
65
|
-
IceCube::I18n.t(
|
62
|
+
IceCube::I18n.t("ice_cube.on_weekdays")
|
66
63
|
else
|
67
|
-
day_names = ->(d){
|
64
|
+
day_names = ->(d) { (IceCube::I18n.t("ice_cube.days_on")[d]).to_s }
|
68
65
|
segments = validation_days.map(&day_names)
|
69
|
-
IceCube::I18n.t(
|
66
|
+
IceCube::I18n.t("ice_cube.on_days", days: StringBuilder.sentence(segments))
|
70
67
|
end
|
71
68
|
end
|
72
|
-
|
73
69
|
end
|
74
|
-
|
75
70
|
end
|
76
|
-
|
77
71
|
end
|