ice_cube 0.16.4 → 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 +4 -4
- data/config/locales/id.yml +134 -0
- 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 -19
- 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 +5 -11
- 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 +23 -8
- data/spec/spec_helper.rb +0 -79
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
|
@@ -1,7 +1,5 @@
|
|
1
1
|
module IceCube
|
2
|
-
|
3
2
|
module Validations::DayOfMonth
|
4
|
-
|
5
3
|
def day_of_month(*days)
|
6
4
|
days.flatten.each do |day|
|
7
5
|
unless day.is_a?(Integer)
|
@@ -15,9 +13,8 @@ module IceCube
|
|
15
13
|
end
|
16
14
|
|
17
15
|
class Validation < Validations::FixedValue
|
18
|
-
|
19
16
|
attr_reader :day
|
20
|
-
|
17
|
+
alias_method :value, :day
|
21
18
|
|
22
19
|
def initialize(day)
|
23
20
|
@day = day
|
@@ -44,17 +41,14 @@ module IceCube
|
|
44
41
|
end
|
45
42
|
|
46
43
|
def build_ical(builder)
|
47
|
-
builder[
|
44
|
+
builder["BYMONTHDAY"] << day
|
48
45
|
end
|
49
46
|
|
50
47
|
StringBuilder.register_formatter(:day_of_month) do |entries|
|
51
48
|
sentence = StringBuilder.sentence(entries)
|
52
|
-
str = IceCube::I18n.t(
|
53
|
-
IceCube::I18n.t(
|
49
|
+
str = IceCube::I18n.t("ice_cube.days_of_month", count: entries.size, segments: sentence)
|
50
|
+
IceCube::I18n.t("ice_cube.on", sentence: str)
|
54
51
|
end
|
55
|
-
|
56
52
|
end
|
57
|
-
|
58
53
|
end
|
59
|
-
|
60
54
|
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
module IceCube
|
2
|
-
|
3
2
|
module Validations::DayOfWeek
|
4
|
-
|
5
3
|
def day_of_week(dows)
|
6
4
|
dows.each do |day, occs|
|
7
5
|
occs.each do |occ|
|
@@ -14,10 +12,12 @@ module IceCube
|
|
14
12
|
end
|
15
13
|
|
16
14
|
class Validation
|
17
|
-
|
18
15
|
attr_reader :day, :occ
|
19
16
|
|
20
17
|
def initialize(day, occ)
|
18
|
+
raise ArgumentError, "Integer occurrence value required" unless occ.is_a?(Integer)
|
19
|
+
raise ArgumentError, "Invalid day_of_week occurrence: #{occ.inspect}" if occ.zero? || occ.abs > 5
|
20
|
+
|
21
21
|
@day = day
|
22
22
|
@occ = occ
|
23
23
|
end
|
@@ -37,7 +37,7 @@ module IceCube
|
|
37
37
|
wrapper.add :day, offset
|
38
38
|
loop do
|
39
39
|
which_occ, num_occ = TimeUtil.which_occurrence_in_month(wrapper.to_time, day)
|
40
|
-
this_occ = (occ < 0) ? (num_occ + occ + 1) :
|
40
|
+
this_occ = (occ < 0) ? (num_occ + occ + 1) : occ
|
41
41
|
break offset if which_occ == this_occ
|
42
42
|
wrapper.add :day, 7
|
43
43
|
offset += 7
|
@@ -46,9 +46,9 @@ module IceCube
|
|
46
46
|
|
47
47
|
def build_s(builder)
|
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(
|
51
|
+
day: IceCube::I18n.t("date.day_names")[day]
|
52
52
|
)
|
53
53
|
end
|
54
54
|
|
@@ -61,17 +61,14 @@ module IceCube
|
|
61
61
|
def build_ical(builder)
|
62
62
|
ical_day = IcalBuilder.fixnum_to_ical_day(day)
|
63
63
|
# Delete any with this day and no occ first
|
64
|
-
builder[
|
65
|
-
builder[
|
64
|
+
builder["BYDAY"].delete_if { |d| d == ical_day }
|
65
|
+
builder["BYDAY"] << "#{occ}#{ical_day}"
|
66
66
|
end
|
67
67
|
|
68
68
|
StringBuilder.register_formatter(:day_of_week) do |segments|
|
69
|
-
sentence = segments.join(IceCube::I18n.t(
|
70
|
-
IceCube::I18n.t(
|
69
|
+
sentence = segments.join(IceCube::I18n.t("ice_cube.array.two_words_connector"))
|
70
|
+
IceCube::I18n.t("ice_cube.on", sentence: sentence)
|
71
71
|
end
|
72
|
-
|
73
72
|
end
|
74
|
-
|
75
73
|
end
|
76
|
-
|
77
74
|
end
|
@@ -1,7 +1,5 @@
|
|
1
1
|
module IceCube
|
2
|
-
|
3
2
|
module Validations::DayOfYear
|
4
|
-
|
5
3
|
def day_of_year(*days)
|
6
4
|
days.flatten.each do |day|
|
7
5
|
unless day.is_a?(Integer)
|
@@ -14,7 +12,6 @@ module IceCube
|
|
14
12
|
end
|
15
13
|
|
16
14
|
class Validation
|
17
|
-
|
18
15
|
attr_reader :day
|
19
16
|
|
20
17
|
def initialize(day)
|
@@ -31,9 +28,9 @@ module IceCube
|
|
31
28
|
|
32
29
|
def validate(step_time, start_time)
|
33
30
|
days_in_year = TimeUtil.days_in_year(step_time)
|
34
|
-
yday = day < 0 ? day + days_in_year + 1 : day
|
31
|
+
yday = (day < 0) ? day + days_in_year + 1 : day
|
35
32
|
offset = yday - step_time.yday
|
36
|
-
offset >= 0 ? offset : offset + days_in_year
|
33
|
+
(offset >= 0) ? offset : offset + days_in_year
|
37
34
|
end
|
38
35
|
|
39
36
|
def build_s(builder)
|
@@ -45,17 +42,14 @@ module IceCube
|
|
45
42
|
end
|
46
43
|
|
47
44
|
def build_ical(builder)
|
48
|
-
builder[
|
45
|
+
builder["BYYEARDAY"] << day
|
49
46
|
end
|
50
47
|
|
51
48
|
StringBuilder.register_formatter(:day_of_year) do |entries|
|
52
|
-
str =
|
53
|
-
sentence = IceCube::I18n.t(
|
54
|
-
IceCube::I18n.t(
|
49
|
+
str = StringBuilder.sentence(entries)
|
50
|
+
sentence = IceCube::I18n.t("ice_cube.days_of_year", count: entries.size, segments: str)
|
51
|
+
IceCube::I18n.t("ice_cube.on", sentence: sentence)
|
55
52
|
end
|
56
|
-
|
57
53
|
end
|
58
|
-
|
59
54
|
end
|
60
|
-
|
61
55
|
end
|
@@ -1,5 +1,4 @@
|
|
1
1
|
module IceCube
|
2
|
-
|
3
2
|
# This abstract validation class is used by the various "fixed-time" (e.g.
|
4
3
|
# day, day_of_month, hour_of_day) Validation and ScheduleLock::Validation
|
5
4
|
# modules. It is not a standalone rule validation module like the others.
|
@@ -9,12 +8,11 @@ module IceCube
|
|
9
8
|
# start_time
|
10
9
|
#
|
11
10
|
class Validations::FixedValue
|
12
|
-
|
13
|
-
INTERVALS = {:min => 60, :sec => 60, :hour => 24, :month => 12, :wday => 7}
|
11
|
+
INTERVALS = {min: 60, sec: 60, hour: 24, month: 12, wday: 7}
|
14
12
|
|
15
13
|
def validate(time, start_time)
|
16
14
|
case type
|
17
|
-
when :day
|
15
|
+
when :day then validate_day_lock(time, start_time)
|
18
16
|
when :hour then validate_hour_lock(time, start_time)
|
19
17
|
else validate_interval_lock(time, start_time)
|
20
18
|
end
|
@@ -28,7 +26,7 @@ module IceCube
|
|
28
26
|
def validate_interval_lock(time, start_time)
|
29
27
|
t0 = starting_unit(start_time)
|
30
28
|
t1 = time.send(type)
|
31
|
-
t0 >= t1 ? t0 - t1 : INTERVALS[type] - t1 + t0
|
29
|
+
(t0 >= t1) ? t0 - t1 : INTERVALS[type] - t1 + t0
|
32
30
|
end
|
33
31
|
|
34
32
|
# Lock the hour if explicitly set by hour_of_day, but allow for the nearest
|
@@ -39,12 +37,10 @@ module IceCube
|
|
39
37
|
h1 = time.hour
|
40
38
|
if h0 >= h1
|
41
39
|
h0 - h1
|
40
|
+
elsif (dst_offset = TimeUtil.dst_change(time))
|
41
|
+
h0 - h1 + dst_offset
|
42
42
|
else
|
43
|
-
|
44
|
-
h0 - h1 + dst_offset
|
45
|
-
else
|
46
|
-
24 - h1 + h0
|
47
|
-
end
|
43
|
+
24 - h1 + h0
|
48
44
|
end
|
49
45
|
end
|
50
46
|
|
@@ -77,19 +73,17 @@ module IceCube
|
|
77
73
|
if value && value > 0
|
78
74
|
until_next_month = days_in_month + sleeps
|
79
75
|
else
|
80
|
-
until_next_month = start < 28 ? days_in_month : TimeUtil.days_to_next_month(date)
|
76
|
+
until_next_month = (start < 28) ? days_in_month : TimeUtil.days_to_next_month(date)
|
81
77
|
until_next_month += sleeps - month_overflow
|
82
78
|
end
|
83
79
|
|
84
|
-
sleeps >= 0 ? sleeps : until_next_month
|
80
|
+
(sleeps >= 0) ? sleeps : until_next_month
|
85
81
|
end
|
86
82
|
|
87
83
|
def starting_unit(start_time)
|
88
84
|
start = value || start_time.send(type)
|
89
|
-
start
|
85
|
+
start %= INTERVALS[type] if start < 0
|
90
86
|
start
|
91
87
|
end
|
92
|
-
|
93
88
|
end
|
94
|
-
|
95
89
|
end
|