ice_cube 0.16.0 → 0.16.4
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/en.yml +7 -46
- data/config/locales/es.yml +47 -83
- data/config/locales/fr.yml +2 -2
- data/config/locales/it.yml +179 -0
- data/config/locales/ja.yml +52 -29
- data/config/locales/nl.yml +133 -0
- data/config/locales/pt-BR.yml +178 -0
- data/config/locales/sv.yml +1 -1
- data/lib/ice_cube/i18n.rb +11 -12
- data/lib/ice_cube/input_alignment.rb +89 -0
- data/lib/ice_cube/null_i18n.rb +12 -6
- data/lib/ice_cube/occurrence.rb +25 -23
- data/lib/ice_cube/parsers/ical_parser.rb +8 -5
- data/lib/ice_cube/rule.rb +5 -13
- data/lib/ice_cube/rules/daily_rule.rb +9 -0
- data/lib/ice_cube/rules/hourly_rule.rb +9 -0
- data/lib/ice_cube/rules/minutely_rule.rb +9 -0
- data/lib/ice_cube/rules/monthly_rule.rb +9 -0
- data/lib/ice_cube/rules/secondly_rule.rb +9 -0
- data/lib/ice_cube/rules/weekly_rule.rb +30 -9
- data/lib/ice_cube/rules/yearly_rule.rb +9 -0
- data/lib/ice_cube/schedule.rb +30 -29
- data/lib/ice_cube/single_occurrence_rule.rb +4 -0
- data/lib/ice_cube/time_util.rb +65 -46
- data/lib/ice_cube/validated_rule.rb +18 -24
- data/lib/ice_cube/validations/count.rb +1 -2
- data/lib/ice_cube/validations/daily_interval.rb +5 -1
- data/lib/ice_cube/validations/day.rb +6 -2
- data/lib/ice_cube/validations/day_of_month.rb +5 -0
- data/lib/ice_cube/validations/day_of_week.rb +1 -1
- data/lib/ice_cube/validations/hour_of_day.rb +23 -0
- data/lib/ice_cube/validations/hourly_interval.rb +2 -0
- data/lib/ice_cube/validations/minute_of_hour.rb +16 -0
- data/lib/ice_cube/validations/minutely_interval.rb +2 -0
- data/lib/ice_cube/validations/month_of_year.rb +6 -1
- data/lib/ice_cube/validations/monthly_interval.rb +4 -1
- data/lib/ice_cube/validations/schedule_lock.rb +4 -0
- data/lib/ice_cube/validations/second_of_minute.rb +19 -3
- data/lib/ice_cube/validations/secondly_interval.rb +2 -0
- data/lib/ice_cube/validations/until.rb +1 -2
- data/lib/ice_cube/validations/weekly_interval.rb +0 -2
- data/lib/ice_cube/version.rb +1 -1
- data/lib/ice_cube.rb +1 -3
- data/spec/spec_helper.rb +32 -9
- metadata +10 -7
@@ -0,0 +1,178 @@
|
|
1
|
+
pt-BR:
|
2
|
+
ice_cube:
|
3
|
+
pieces_connector: ' / '
|
4
|
+
not: 'exceto %{target}'
|
5
|
+
not_on: 'exceto o dia %{target}'
|
6
|
+
date:
|
7
|
+
formats:
|
8
|
+
default: '%-d %B %Y'
|
9
|
+
month_names:
|
10
|
+
-
|
11
|
+
- Janeiro
|
12
|
+
- Fevereiro
|
13
|
+
- Março
|
14
|
+
- Abril
|
15
|
+
- Maio
|
16
|
+
- Junho
|
17
|
+
- Julho
|
18
|
+
- Agosto
|
19
|
+
- Setembro
|
20
|
+
- Outubro
|
21
|
+
- Novembro
|
22
|
+
- Dezembro
|
23
|
+
day_names:
|
24
|
+
- Domingo
|
25
|
+
- Segunda
|
26
|
+
- Terça
|
27
|
+
- Quarta
|
28
|
+
- Quinta
|
29
|
+
- Sexta
|
30
|
+
- Sábado
|
31
|
+
times:
|
32
|
+
other: '%{count} vezes'
|
33
|
+
one: '%{count} vez'
|
34
|
+
until: 'até %{date}'
|
35
|
+
days_of_week: '%{segments} %{day}'
|
36
|
+
days_of_month:
|
37
|
+
other: '%{segments} dias do mês'
|
38
|
+
one: '%{segments} dia'
|
39
|
+
days_of_year:
|
40
|
+
other: '%{segments} dias do ano'
|
41
|
+
one: '%{segments} dia'
|
42
|
+
at_hours_of_the_day:
|
43
|
+
other: às %{segments} horas
|
44
|
+
one: à %{segments} hora
|
45
|
+
on_minutes_of_hour:
|
46
|
+
other: aos %{segments} minutos
|
47
|
+
one: ao %{segments} minuto
|
48
|
+
at_seconds_of_minute:
|
49
|
+
other: aos %{segments} segundos
|
50
|
+
one: ao %{segments} segundo
|
51
|
+
on_seconds_of_minute:
|
52
|
+
other: aos %{segments} segundos
|
53
|
+
one: ao %{segments} segundo
|
54
|
+
each_second:
|
55
|
+
one: A cada segundo
|
56
|
+
other: A cada %{count} segundos
|
57
|
+
each_minute:
|
58
|
+
one: A cada minuto
|
59
|
+
other: A cada %{count} minutos
|
60
|
+
each_hour:
|
61
|
+
one: A cada hora
|
62
|
+
other: A cada %{count} horas
|
63
|
+
each_day:
|
64
|
+
one: Diariamente
|
65
|
+
other: A cada %{count} dias
|
66
|
+
each_week:
|
67
|
+
one: Semanalmente
|
68
|
+
other: A cada %{count} semanas
|
69
|
+
each_month:
|
70
|
+
one: Mensalmente
|
71
|
+
other: A cada %{count} meses
|
72
|
+
each_year:
|
73
|
+
one: Anualmente
|
74
|
+
other: A cada %{count} anos
|
75
|
+
'on': no %{sentence}
|
76
|
+
in: 'em %{target}'
|
77
|
+
integer:
|
78
|
+
negative: '%{ordinal} depois que acabar'
|
79
|
+
literal_ordinals:
|
80
|
+
-1: último
|
81
|
+
-2: penúltimo
|
82
|
+
ordinal: '%{number}%{ordinal}'
|
83
|
+
ordinals:
|
84
|
+
default: º
|
85
|
+
1: º
|
86
|
+
2: º
|
87
|
+
3: º
|
88
|
+
11: º
|
89
|
+
12: º
|
90
|
+
13: º
|
91
|
+
on_weekends: nos finais de semana
|
92
|
+
on_weekdays: nos dias úteis
|
93
|
+
days_on:
|
94
|
+
- Domingos
|
95
|
+
- Segundas-feiras
|
96
|
+
- Terças-feiras
|
97
|
+
- Quartas-feiras
|
98
|
+
- Quintas-feiras
|
99
|
+
- Sextas-feiras
|
100
|
+
- Sábados
|
101
|
+
on_days: no dia %{days}
|
102
|
+
array:
|
103
|
+
last_word_connector: ' e '
|
104
|
+
two_words_connector: ' e '
|
105
|
+
words_connector: ', '
|
106
|
+
string:
|
107
|
+
format:
|
108
|
+
day: '%{rest} %{current}'
|
109
|
+
day_of_week: '%{rest} %{current}'
|
110
|
+
day_of_month: '%{rest} %{current}'
|
111
|
+
day_of_year: '%{rest} %{current}'
|
112
|
+
hour_of_day: '%{rest} %{current}'
|
113
|
+
minute_of_hour: '%{rest} %{current}'
|
114
|
+
until: '%{rest} %{current}'
|
115
|
+
count: '%{rest} %{current}'
|
116
|
+
default: '%{rest} %{current}'
|
117
|
+
|
118
|
+
date:
|
119
|
+
abbr_day_names:
|
120
|
+
- Dom
|
121
|
+
- Seg
|
122
|
+
- Ter
|
123
|
+
- Qua
|
124
|
+
- Qui
|
125
|
+
- Sex
|
126
|
+
- Sáb
|
127
|
+
abbr_month_names:
|
128
|
+
-
|
129
|
+
- Jan
|
130
|
+
- Fev
|
131
|
+
- Mar
|
132
|
+
- Abr
|
133
|
+
- Mai
|
134
|
+
- Jun
|
135
|
+
- Jul
|
136
|
+
- Ago
|
137
|
+
- Set
|
138
|
+
- Out
|
139
|
+
- Nov
|
140
|
+
- Dez
|
141
|
+
day_names:
|
142
|
+
- Domingo
|
143
|
+
- Segunda-feira
|
144
|
+
- Terça-feira
|
145
|
+
- Quarta-feira
|
146
|
+
- Quinta-feira
|
147
|
+
- Sexta-feira
|
148
|
+
- Sábado
|
149
|
+
formats:
|
150
|
+
default: "%d/%m/%Y"
|
151
|
+
long: "%d de %B de %Y"
|
152
|
+
short: "%d de %B"
|
153
|
+
month_names:
|
154
|
+
-
|
155
|
+
- Janeiro
|
156
|
+
- Fevereiro
|
157
|
+
- Março
|
158
|
+
- Abril
|
159
|
+
- Maio
|
160
|
+
- Junho
|
161
|
+
- Julho
|
162
|
+
- Agosto
|
163
|
+
- Setembro
|
164
|
+
- Outubro
|
165
|
+
- Novembro
|
166
|
+
- Dezembro
|
167
|
+
order:
|
168
|
+
- :day
|
169
|
+
- :month
|
170
|
+
- :year
|
171
|
+
|
172
|
+
time:
|
173
|
+
am: ''
|
174
|
+
formats:
|
175
|
+
default: "%a, %d de %B de %Y, %H:%M:%S %z"
|
176
|
+
long: "%d de %B de %Y, %H:%M"
|
177
|
+
short: "%d de %B, %H:%M"
|
178
|
+
pm: ''
|
data/config/locales/sv.yml
CHANGED
data/lib/ice_cube/i18n.rb
CHANGED
@@ -1,24 +1,23 @@
|
|
1
|
+
require 'ice_cube/null_i18n'
|
2
|
+
|
1
3
|
module IceCube
|
2
4
|
module I18n
|
3
|
-
def self.t(*args)
|
4
|
-
backend.t(*args)
|
5
|
-
end
|
6
5
|
|
7
|
-
|
8
|
-
|
6
|
+
LOCALES_PATH = File.expand_path(File.join('..', '..', '..', 'config', 'locales'), __FILE__)
|
7
|
+
|
8
|
+
class << self
|
9
|
+
delegate :t, :l, to: :backend
|
9
10
|
end
|
10
11
|
|
11
12
|
def self.backend
|
12
|
-
@backend
|
13
|
+
@backend ||= detect_backend!
|
13
14
|
end
|
14
15
|
|
15
16
|
def self.detect_backend!
|
16
|
-
|
17
|
-
::I18n
|
18
|
-
|
19
|
-
|
20
|
-
require 'ice_cube/null_i18n'
|
21
|
-
@backend = NullI18n
|
17
|
+
::I18n.load_path += Dir[File.join(LOCALES_PATH, '*.yml')]
|
18
|
+
::I18n
|
19
|
+
rescue NameError
|
20
|
+
NullI18n
|
22
21
|
end
|
23
22
|
end
|
24
23
|
end
|
@@ -0,0 +1,89 @@
|
|
1
|
+
module IceCube
|
2
|
+
class InputAlignment
|
3
|
+
|
4
|
+
def initialize(rule, value, rule_part)
|
5
|
+
@rule = rule
|
6
|
+
@value = value
|
7
|
+
@rule_part = rule_part
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :rule, :value, :rule_part
|
11
|
+
|
12
|
+
def verify(freq, options={}, &block)
|
13
|
+
@rule.validations[:interval] or return
|
14
|
+
|
15
|
+
case @rule
|
16
|
+
when DailyRule
|
17
|
+
verify_wday_alignment(freq, &block)
|
18
|
+
when MonthlyRule
|
19
|
+
verify_month_alignment(freq, &block)
|
20
|
+
else
|
21
|
+
verify_freq_alignment(freq, &block)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def interval_validation
|
28
|
+
@interval_validation ||= @rule.validations[:interval].first
|
29
|
+
end
|
30
|
+
|
31
|
+
def interval_value
|
32
|
+
@interval_value ||= (rule_part == :interval) ? value : interval_validation.interval
|
33
|
+
end
|
34
|
+
|
35
|
+
def fixed_validations
|
36
|
+
@fixed_validations ||= @rule.validations.values.flatten.select { |v|
|
37
|
+
interval_type = (v.type == :wday ? :day : v.type)
|
38
|
+
v.class < Validations::FixedValue &&
|
39
|
+
interval_type == rule.base_interval_validation.type
|
40
|
+
}
|
41
|
+
end
|
42
|
+
|
43
|
+
def verify_freq_alignment(freq)
|
44
|
+
interval_validation.type == freq or return
|
45
|
+
(last_validation = fixed_validations.min_by(&:value)) or return
|
46
|
+
|
47
|
+
alignment = (value - last_validation.value) % interval_validation.interval
|
48
|
+
return if alignment.zero?
|
49
|
+
|
50
|
+
validation_values = fixed_validations.map(&:value).join(', ')
|
51
|
+
if rule_part == :interval
|
52
|
+
message = "interval(#{value}) " \
|
53
|
+
"must be a multiple of " \
|
54
|
+
"intervals in #{last_validation.key}(#{validation_values})"
|
55
|
+
else
|
56
|
+
message = "intervals in #{last_validation.key}(#{validation_values}, #{value}) " \
|
57
|
+
"must be multiples of " \
|
58
|
+
"interval(#{interval_validation.interval})"
|
59
|
+
end
|
60
|
+
|
61
|
+
yield ArgumentError.new(message)
|
62
|
+
end
|
63
|
+
|
64
|
+
def verify_month_alignment(_freq)
|
65
|
+
return if interval_value == 1 || (interval_value % 12).zero?
|
66
|
+
return if fixed_validations.empty?
|
67
|
+
|
68
|
+
message = "month_of_year can only be used with interval(1) or multiples of interval(12)"
|
69
|
+
|
70
|
+
yield ArgumentError.new(message)
|
71
|
+
end
|
72
|
+
|
73
|
+
def verify_wday_alignment(freq)
|
74
|
+
return if interval_value == 1
|
75
|
+
|
76
|
+
if freq == :wday
|
77
|
+
return if (interval_value % 7).zero?
|
78
|
+
return if Array(@rule.validations[:day]).empty?
|
79
|
+
message = "day can only be used with multiples of interval(7)"
|
80
|
+
else
|
81
|
+
(fixed_validation = fixed_validations.first) or return
|
82
|
+
message = "#{fixed_validation.key} can only be used with interval(1)"
|
83
|
+
end
|
84
|
+
|
85
|
+
yield ArgumentError.new(message)
|
86
|
+
end
|
87
|
+
|
88
|
+
end
|
89
|
+
end
|
data/lib/ice_cube/null_i18n.rb
CHANGED
@@ -7,13 +7,19 @@ module IceCube
|
|
7
7
|
|
8
8
|
base = base[options[:count] == 1 ? "one" : "other"] if options[:count]
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
|
10
|
+
case base
|
11
|
+
when Hash
|
12
|
+
base.each_with_object({}) do |(k, v), hash|
|
13
|
+
hash[k.is_a?(String) ? k.to_sym : k] = v
|
13
14
|
end
|
15
|
+
when Array
|
16
|
+
base.each_with_index.each_with_object({}) do |(v, k), hash|
|
17
|
+
hash[k] = v
|
18
|
+
end
|
19
|
+
else
|
20
|
+
return base unless base.include?('%{')
|
21
|
+
base % options
|
14
22
|
end
|
15
|
-
|
16
|
-
options.reduce(base) { |result, (find, replace)| result.gsub("%{#{find}}", "#{replace}") }
|
17
23
|
end
|
18
24
|
|
19
25
|
def self.l(date_or_time, options = {})
|
@@ -22,7 +28,7 @@ module IceCube
|
|
22
28
|
end
|
23
29
|
|
24
30
|
def self.config
|
25
|
-
@config ||= YAML.
|
31
|
+
@config ||= YAML.load_file(File.join(IceCube::I18n::LOCALES_PATH, 'en.yml'))['en']
|
26
32
|
end
|
27
33
|
end
|
28
34
|
end
|
data/lib/ice_cube/occurrence.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require 'forwardable'
|
2
1
|
require 'delegate'
|
3
2
|
|
4
3
|
module IceCube
|
@@ -20,18 +19,16 @@ module IceCube
|
|
20
19
|
# Time.now - Occurrence.new(start_time) # => 3600
|
21
20
|
#
|
22
21
|
class Occurrence < SimpleDelegator
|
22
|
+
include Comparable
|
23
23
|
|
24
24
|
# Report class name as 'Time' to thwart type checking.
|
25
25
|
def self.name
|
26
26
|
'Time'
|
27
27
|
end
|
28
28
|
|
29
|
-
# Optimize for common methods to avoid method_missing
|
30
|
-
extend Forwardable
|
31
|
-
def_delegators :start_time, :to_i, :<=>, :==
|
32
|
-
def_delegators :to_range, :cover?, :include?, :each, :first, :last
|
33
|
-
|
34
29
|
attr_reader :start_time, :end_time
|
30
|
+
alias first start_time
|
31
|
+
alias last end_time
|
35
32
|
|
36
33
|
def initialize(start_time, end_time=nil)
|
37
34
|
@start_time = start_time
|
@@ -39,29 +36,34 @@ module IceCube
|
|
39
36
|
__setobj__ @start_time
|
40
37
|
end
|
41
38
|
|
39
|
+
def to_i
|
40
|
+
@start_time.to_i
|
41
|
+
end
|
42
|
+
|
43
|
+
def <=>(other)
|
44
|
+
@start_time <=> other
|
45
|
+
end
|
46
|
+
|
42
47
|
def is_a?(klass)
|
43
48
|
klass == ::Time || super
|
44
49
|
end
|
45
50
|
alias_method :kind_of?, :is_a?
|
46
51
|
|
47
|
-
def intersects?
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
end
|
61
|
-
else
|
62
|
-
cover? other
|
63
|
-
end
|
52
|
+
def intersects?(other)
|
53
|
+
return cover?(other) unless other.is_a?(Occurrence) || other.is_a?(Range)
|
54
|
+
|
55
|
+
this_start = first + 1
|
56
|
+
this_end = last # exclude end boundary
|
57
|
+
other_start = other.first + 1
|
58
|
+
other_end = other.last + 1
|
59
|
+
|
60
|
+
!(this_end < other_start || this_start > other_end)
|
61
|
+
end
|
62
|
+
|
63
|
+
def cover?(other)
|
64
|
+
to_range.cover?(other)
|
64
65
|
end
|
66
|
+
alias_method :include?, :cover?
|
65
67
|
|
66
68
|
def comparable_time
|
67
69
|
start_time
|
@@ -4,15 +4,18 @@ module IceCube
|
|
4
4
|
data = {}
|
5
5
|
ical_string.each_line do |line|
|
6
6
|
(property, value) = line.split(':')
|
7
|
-
(property,
|
7
|
+
(property, _tzid) = property.split(';')
|
8
8
|
case property
|
9
9
|
when 'DTSTART'
|
10
|
-
data[:start_time] =
|
10
|
+
data[:start_time] = TimeUtil.deserialize_time(value)
|
11
11
|
when 'DTEND'
|
12
|
-
data[:end_time] =
|
12
|
+
data[:end_time] = TimeUtil.deserialize_time(value)
|
13
|
+
when 'RDATE'
|
14
|
+
data[:rtimes] ||= []
|
15
|
+
data[:rtimes] += value.split(',').map { |v| TimeUtil.deserialize_time(v) }
|
13
16
|
when 'EXDATE'
|
14
17
|
data[:extimes] ||= []
|
15
|
-
data[:extimes] += value.split(',').map{|v|
|
18
|
+
data[:extimes] += value.split(',').map { |v| TimeUtil.deserialize_time(v) }
|
16
19
|
when 'DURATION'
|
17
20
|
data[:duration] # FIXME
|
18
21
|
when 'RRULE'
|
@@ -41,7 +44,7 @@ module IceCube
|
|
41
44
|
when 'COUNT'
|
42
45
|
params[:count] = value.to_i
|
43
46
|
when 'UNTIL'
|
44
|
-
params[:until] =
|
47
|
+
params[:until] = TimeUtil.deserialize_time(value).utc
|
45
48
|
when 'WKST'
|
46
49
|
params[:week_start] = TimeUtil.ical_day_to_symbol(value)
|
47
50
|
when 'BYSECOND'
|
data/lib/ice_cube/rule.rb
CHANGED
@@ -19,20 +19,17 @@ module IceCube
|
|
19
19
|
until_time || occurrence_count
|
20
20
|
end
|
21
21
|
|
22
|
-
def ==(
|
23
|
-
|
24
|
-
|
25
|
-
hash && hash == rule.to_hash
|
26
|
-
end
|
22
|
+
def ==(other)
|
23
|
+
return false unless other.is_a? Rule
|
24
|
+
hash == other.hash
|
27
25
|
end
|
28
26
|
|
29
27
|
def hash
|
30
|
-
|
31
|
-
h.nil? ? super : h.hash
|
28
|
+
to_hash.hash
|
32
29
|
end
|
33
30
|
|
34
31
|
def to_ical
|
35
|
-
raise MethodNotImplemented, "Expected to be
|
32
|
+
raise MethodNotImplemented, "Expected to be overridden by subclasses"
|
36
33
|
end
|
37
34
|
|
38
35
|
# Convert from ical string and create a rule
|
@@ -61,11 +58,6 @@ module IceCube
|
|
61
58
|
next_time(time, schedule, time).to_i == time.to_i
|
62
59
|
end
|
63
60
|
|
64
|
-
# Whether this rule requires a full run
|
65
|
-
def full_required?
|
66
|
-
!@count.nil?
|
67
|
-
end
|
68
|
-
|
69
61
|
class << self
|
70
62
|
|
71
63
|
# Convert from a hash and create a rule
|
@@ -2,6 +2,15 @@ module IceCube
|
|
2
2
|
|
3
3
|
class DailyRule < ValidatedRule
|
4
4
|
|
5
|
+
include Validations::HourOfDay
|
6
|
+
include Validations::MinuteOfHour
|
7
|
+
include Validations::SecondOfMinute
|
8
|
+
include Validations::DayOfMonth
|
9
|
+
include Validations::DayOfWeek
|
10
|
+
include Validations::Day
|
11
|
+
include Validations::MonthOfYear
|
12
|
+
# include Validations::DayOfYear # n/a
|
13
|
+
|
5
14
|
include Validations::DailyInterval
|
6
15
|
|
7
16
|
def initialize(interval = 1)
|
@@ -2,6 +2,15 @@ module IceCube
|
|
2
2
|
|
3
3
|
class HourlyRule < ValidatedRule
|
4
4
|
|
5
|
+
include Validations::HourOfDay
|
6
|
+
include Validations::MinuteOfHour
|
7
|
+
include Validations::SecondOfMinute
|
8
|
+
include Validations::DayOfMonth
|
9
|
+
include Validations::DayOfWeek
|
10
|
+
include Validations::Day
|
11
|
+
include Validations::MonthOfYear
|
12
|
+
include Validations::DayOfYear
|
13
|
+
|
5
14
|
include Validations::HourlyInterval
|
6
15
|
|
7
16
|
def initialize(interval = 1)
|
@@ -2,6 +2,15 @@ module IceCube
|
|
2
2
|
|
3
3
|
class MinutelyRule < ValidatedRule
|
4
4
|
|
5
|
+
include Validations::HourOfDay
|
6
|
+
include Validations::MinuteOfHour
|
7
|
+
include Validations::SecondOfMinute
|
8
|
+
include Validations::DayOfMonth
|
9
|
+
include Validations::DayOfWeek
|
10
|
+
include Validations::Day
|
11
|
+
include Validations::MonthOfYear
|
12
|
+
include Validations::DayOfYear
|
13
|
+
|
5
14
|
include Validations::MinutelyInterval
|
6
15
|
|
7
16
|
def initialize(interval = 1)
|
@@ -2,6 +2,15 @@ module IceCube
|
|
2
2
|
|
3
3
|
class MonthlyRule < ValidatedRule
|
4
4
|
|
5
|
+
include Validations::HourOfDay
|
6
|
+
include Validations::MinuteOfHour
|
7
|
+
include Validations::SecondOfMinute
|
8
|
+
include Validations::DayOfMonth
|
9
|
+
include Validations::DayOfWeek
|
10
|
+
include Validations::Day
|
11
|
+
include Validations::MonthOfYear
|
12
|
+
# include Validations::DayOfYear # n/a
|
13
|
+
|
5
14
|
include Validations::MonthlyInterval
|
6
15
|
|
7
16
|
def initialize(interval = 1)
|
@@ -2,6 +2,15 @@ module IceCube
|
|
2
2
|
|
3
3
|
class SecondlyRule < ValidatedRule
|
4
4
|
|
5
|
+
include Validations::HourOfDay
|
6
|
+
include Validations::MinuteOfHour
|
7
|
+
include Validations::SecondOfMinute
|
8
|
+
include Validations::DayOfMonth
|
9
|
+
include Validations::DayOfWeek
|
10
|
+
include Validations::Day
|
11
|
+
include Validations::MonthOfYear
|
12
|
+
include Validations::DayOfYear
|
13
|
+
|
5
14
|
include Validations::SecondlyInterval
|
6
15
|
|
7
16
|
def initialize(interval = 1)
|
@@ -2,6 +2,15 @@ module IceCube
|
|
2
2
|
|
3
3
|
class WeeklyRule < ValidatedRule
|
4
4
|
|
5
|
+
include Validations::HourOfDay
|
6
|
+
include Validations::MinuteOfHour
|
7
|
+
include Validations::SecondOfMinute
|
8
|
+
# include Validations::DayOfMonth # n/a
|
9
|
+
include Validations::DayOfWeek
|
10
|
+
include Validations::Day
|
11
|
+
include Validations::MonthOfYear
|
12
|
+
# include Validations::DayOfYear # n/a
|
13
|
+
|
5
14
|
include Validations::WeeklyInterval
|
6
15
|
|
7
16
|
attr_reader :week_start
|
@@ -13,25 +22,37 @@ module IceCube
|
|
13
22
|
reset
|
14
23
|
end
|
15
24
|
|
16
|
-
#
|
17
|
-
# in the week than
|
18
|
-
#
|
19
|
-
#
|
25
|
+
# Move the effective start time to correct for when the schedule has
|
26
|
+
# validations earlier in the week than the selected start time, e.g.
|
27
|
+
#
|
28
|
+
# Schedule.new(wednesday).weekly(2).day(:monday)
|
29
|
+
#
|
30
|
+
# The effective start time gets realigned to the second next Monday, jumping
|
31
|
+
# over the gap week for the interval (2). Without realignment, the correct
|
32
|
+
# Monday occurrence would be missed when the schedule performs a 7-day jump
|
33
|
+
# into the next interval week, arriving on the Wednesday. This corrects any
|
34
|
+
# selections from dates that are misaligned to the schedule interval.
|
20
35
|
#
|
21
36
|
def realign(step_time, start_time)
|
22
37
|
time = TimeUtil::TimeWrapper.new(start_time)
|
23
38
|
offset = wday_offset(step_time, start_time)
|
24
|
-
time.add(:day, offset)
|
25
|
-
time.to_time
|
39
|
+
time.add(:day, offset)
|
40
|
+
super step_time, time.to_time
|
26
41
|
end
|
27
42
|
|
43
|
+
# Calculate how many days to the first wday validation in the correct
|
44
|
+
# interval week. This may move backwards within the week if starting in an
|
45
|
+
# interval week with earlier validations.
|
46
|
+
#
|
28
47
|
def wday_offset(step_time, start_time)
|
48
|
+
return 0 if step_time == start_time
|
49
|
+
|
29
50
|
wday_validations = other_interval_validations.select { |v| v.type == :wday }
|
30
|
-
return if wday_validations.none?
|
51
|
+
return 0 if wday_validations.none?
|
31
52
|
|
32
|
-
days =
|
53
|
+
days = step_time.to_date - start_time.to_date
|
33
54
|
interval = base_interval_validation.validate(step_time, start_time).to_i
|
34
|
-
min_wday = TimeUtil.normalize_wday(
|
55
|
+
min_wday = wday_validations.map { |v| TimeUtil.normalize_wday(v.day, week_start) }.min
|
35
56
|
step_wday = TimeUtil.normalize_wday(step_time.wday, week_start)
|
36
57
|
|
37
58
|
days + interval - step_wday + min_wday
|
@@ -2,6 +2,15 @@ module IceCube
|
|
2
2
|
|
3
3
|
class YearlyRule < ValidatedRule
|
4
4
|
|
5
|
+
include Validations::HourOfDay
|
6
|
+
include Validations::MinuteOfHour
|
7
|
+
include Validations::SecondOfMinute
|
8
|
+
include Validations::DayOfMonth
|
9
|
+
include Validations::DayOfWeek
|
10
|
+
include Validations::Day
|
11
|
+
include Validations::MonthOfYear
|
12
|
+
include Validations::DayOfYear
|
13
|
+
|
5
14
|
include Validations::YearlyInterval
|
6
15
|
|
7
16
|
def initialize(interval = 1)
|