opening_hours_converter 1.8.1 → 1.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/lib/opening_hours_converter.rb +6 -0
- data/lib/opening_hours_converter/iterator.rb +3 -14
- data/lib/opening_hours_converter/opening_hours_builder.rb +82 -21
- data/lib/opening_hours_converter/opening_hours_date.rb +1 -1
- data/lib/opening_hours_converter/opening_hours_parser.rb +185 -30
- data/lib/opening_hours_converter/opening_hours_rule.rb +67 -38
- data/lib/opening_hours_converter/wide_interval.rb +158 -9
- data/lib/opening_hours_converter/year.rb +53 -1
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0421f6038fb3bcaae15b1e29d5a4bb90b08d829e4bd68d2d4c3501307fa8b8c7
|
4
|
+
data.tar.gz: '059ed79dab312bfa859028e9ec420ff99ae0e718a8723b98e61622fea8f85ae6'
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9319c1fc314fe58bbad62abf9e59c3525069f7324189dda6f938dad328869cd6a5b63ba65ab6965b3e3286e8bce782777d4be88bbac541a87daba0568071e0cb
|
7
|
+
data.tar.gz: 26304defc99f58cceab36cf8bf0ae773651c2ab641b490601d1ff8b60446441af3c52234016e2a19ea73e1648ae05f014087eef9a8dcf5ce8ab1b16dcb5eea22
|
@@ -1,6 +1,11 @@
|
|
1
1
|
module OpeningHoursConverter
|
2
2
|
require 'date'
|
3
|
+
require 'pry'
|
4
|
+
require_relative './opening_hours_converter/utils'
|
3
5
|
require_relative './opening_hours_converter/date_range'
|
6
|
+
require_relative './opening_hours_converter/token'
|
7
|
+
require_relative './opening_hours_converter/tokenizer'
|
8
|
+
require_relative './opening_hours_converter/tokens_handler'
|
4
9
|
require_relative './opening_hours_converter/day'
|
5
10
|
require_relative './opening_hours_converter/week'
|
6
11
|
require_relative './opening_hours_converter/year'
|
@@ -13,4 +18,5 @@ module OpeningHoursConverter
|
|
13
18
|
require_relative './opening_hours_converter/opening_hours_rule'
|
14
19
|
require_relative './opening_hours_converter/opening_hours_time'
|
15
20
|
require_relative './opening_hours_converter/wide_interval'
|
21
|
+
require_relative './opening_hours_converter/week_index'
|
16
22
|
end
|
@@ -3,6 +3,7 @@ require 'opening_hours_converter/constants'
|
|
3
3
|
module OpeningHoursConverter
|
4
4
|
class Iterator
|
5
5
|
include Constants
|
6
|
+
include Utils
|
6
7
|
|
7
8
|
def get_iterator(date_ranges)
|
8
9
|
date_ranges_array = []
|
@@ -78,7 +79,7 @@ module OpeningHoursConverter
|
|
78
79
|
end
|
79
80
|
date_ranges[index].typical.intervals.each do |i|
|
80
81
|
next unless !i.nil? && !i.is_off
|
81
|
-
next unless (i.day_start..i.day_end).cover?(
|
82
|
+
next unless (i.day_start..i.day_end).cover?(reindex_sunday_week_to_monday_week(day.wday)) || (is_ph && year_ph.include?(Time.new(day.year, day.month, day.day)))
|
82
83
|
itr = { start: Time.new(day.year, day.month, day.day, i.start / 60, i.start % 60),
|
83
84
|
end: Time.new(day.year, day.month, day.day, i.end / 60, i.end % 60) }
|
84
85
|
datetime_result << itr unless datetime_result.include?(itr)
|
@@ -98,7 +99,7 @@ module OpeningHoursConverter
|
|
98
99
|
result.each do |interval|
|
99
100
|
(interval[:start]..interval[:end]).each do |day|
|
100
101
|
date_ranges[index].typical.intervals.each do |i|
|
101
|
-
if (i.day_start..i.day_end).cover?(
|
102
|
+
if (i.day_start..i.day_end).cover?(reindex_sunday_week_to_monday_week(day.wday))
|
102
103
|
datetime_result << { start: DateTime.new(day.year, day.month, day.day, i.start / 60, i.start % 60),
|
103
104
|
end: DateTime.new(day.year, day.month, day.day, i.end / 60, i.end % 60) }
|
104
105
|
end
|
@@ -110,10 +111,6 @@ module OpeningHoursConverter
|
|
110
111
|
datetime_result.sort_by { |a| a[:start] }
|
111
112
|
end
|
112
113
|
|
113
|
-
def fix_datetime_wday(d)
|
114
|
-
d == 0 ? 6 : d - 1
|
115
|
-
end
|
116
|
-
|
117
114
|
# A partir d'une string OH et d'une DateTime (= now par défaut), renvoyer le current state (début / fin / commentaire)
|
118
115
|
def state(opening_hours_string, time = Time.now)
|
119
116
|
date_ranges = OpeningHoursConverter::OpeningHoursParser.new.parse(opening_hours_string)
|
@@ -154,13 +151,5 @@ module OpeningHoursConverter
|
|
154
151
|
end
|
155
152
|
false
|
156
153
|
end
|
157
|
-
|
158
|
-
def datetime_to_time(datetime)
|
159
|
-
Time.new(datetime.year, datetime.month, datetime.day, datetime.hour, datetime.min, datetime.sec, datetime.zone)
|
160
|
-
end
|
161
|
-
|
162
|
-
def time_to_datetime(time)
|
163
|
-
DateTime.new(time.year, time.month, time.day, time.hour, time.min, time.sec, Rational(time.gmt_offset / 3600, 24))
|
164
|
-
end
|
165
154
|
end
|
166
155
|
end
|
@@ -10,21 +10,25 @@ module OpeningHoursConverter
|
|
10
10
|
oh_rule_added = nil
|
11
11
|
range_general = nil
|
12
12
|
range_general_for = nil
|
13
|
-
day_ph = false
|
14
|
-
off_day_ph = false
|
15
13
|
|
16
14
|
date_ranges.each_with_index do |date_range, date_range_index|
|
17
15
|
next unless !date_range.nil?
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
16
|
+
|
17
|
+
day_ph = false
|
18
|
+
off_day_ph = false
|
19
|
+
phs = []
|
20
|
+
|
21
|
+
date_range.typical.intervals.each_with_index do |interval, interval_id|
|
22
|
+
next unless interval&.day_start == -2 && interval&.day_start == interval&.day_end
|
23
|
+
|
24
|
+
if interval.is_off
|
25
|
+
off_day_ph = true
|
26
|
+
else
|
27
|
+
day_ph = true
|
27
28
|
end
|
29
|
+
|
30
|
+
phs << interval
|
31
|
+
date_range.typical.remove_interval(interval_id)
|
28
32
|
end
|
29
33
|
|
30
34
|
range_general = nil
|
@@ -44,9 +48,7 @@ module OpeningHoursConverter
|
|
44
48
|
end
|
45
49
|
|
46
50
|
next unless date_range_index == 0 || range_general.nil?
|
47
|
-
if date_range.
|
48
|
-
oh_rules = build_holiday(date_range)
|
49
|
-
elsif date_range.defines_typical_week?
|
51
|
+
if date_range.defines_typical_week?
|
50
52
|
oh_rules = if !range_general_for.nil?
|
51
53
|
build_week_diff(date_range, date_ranges[range_general_for])
|
52
54
|
else
|
@@ -72,7 +74,6 @@ module OpeningHoursConverter
|
|
72
74
|
end
|
73
75
|
oh_rule_added = true
|
74
76
|
rescue Exception => e
|
75
|
-
puts e
|
76
77
|
if oh_rule.date[0].wide_interval.type == 'holiday' && oh_rule.date[0].wide_interval.get_time_selector == 'PH'
|
77
78
|
rules[rule_index].add_ph_weekday
|
78
79
|
oh_rule_added = true
|
@@ -89,12 +90,38 @@ module OpeningHoursConverter
|
|
89
90
|
end
|
90
91
|
end
|
91
92
|
|
92
|
-
|
93
|
+
if off_day_ph || day_ph
|
94
|
+
if date_range.typical.intervals.uniq == [nil]
|
95
|
+
oh_rule.date.first.weekdays = [-2]
|
96
|
+
if off_day_ph
|
97
|
+
oh_rule.is_defined_off = off_day_ph
|
98
|
+
phs = []
|
99
|
+
else
|
100
|
+
phs.reverse.each do |interval|
|
101
|
+
oh_rule.add_time(OpeningHoursConverter::OpeningHoursTime.new(interval.start, interval.end))
|
102
|
+
end
|
103
|
+
end
|
104
|
+
else
|
105
|
+
if times_are_compatible?(oh_rule, phs)
|
106
|
+
holiday_intervals = get_compatible_intervals(oh_rule, phs)
|
107
|
+
oh_rule.add_ph_weekday if holiday_intervals[:compatible].length > 0
|
108
|
+
rules << oh_rule if !oh_rule_added
|
109
|
+
oh_rule_added = true
|
110
|
+
holiday_intervals[:incompatible].each do |interval|
|
111
|
+
rules += build_off_holiday(date_range) if off_day_ph
|
112
|
+
rules += build_holiday(date_range) if day_ph
|
113
|
+
end
|
114
|
+
else
|
115
|
+
rules << oh_rule if !oh_rule_added
|
116
|
+
oh_rule_added = true
|
117
|
+
rules += build_off_holiday(date_range) if off_day_ph
|
118
|
+
rules += build_holiday(date_range) if day_ph
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
93
122
|
|
94
123
|
rules << oh_rule if !oh_rule_added
|
95
124
|
|
96
|
-
rules += build_off_holiday(date_range) if off_day_ph
|
97
|
-
|
98
125
|
next unless oh_rule == oh_rules.last && oh_rule.has_overwritten_weekday?
|
99
126
|
oh_rule_over = OpeningHoursConverter::OpeningHoursRule.new
|
100
127
|
|
@@ -118,6 +145,34 @@ module OpeningHoursConverter
|
|
118
145
|
result.strip
|
119
146
|
end
|
120
147
|
|
148
|
+
def times_are_compatible?(oh_rule, phs)
|
149
|
+
if oh_rule.is_defined_off
|
150
|
+
phs.any?(&:is_off)
|
151
|
+
else
|
152
|
+
phs.any? do |ph_interval|
|
153
|
+
oh_rule.time.any? do |rule_time|
|
154
|
+
rule_time.start == ph_interval.start && rule_time.end == ph_interval.end
|
155
|
+
end
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|
159
|
+
|
160
|
+
def get_compatible_intervals(oh_rule, phs)
|
161
|
+
compatibility = {
|
162
|
+
compatible: [],
|
163
|
+
incompatible: []
|
164
|
+
}
|
165
|
+
|
166
|
+
compatibility[:compatible] = phs.select do |ph_interval|
|
167
|
+
return false if ph_interval.is_off != oh_rule.is_defined_off
|
168
|
+
|
169
|
+
oh_rule.time.any? { |rule_time| rule_time.start == ph_interval.start && rule_time.end == ph_interval.end }
|
170
|
+
end
|
171
|
+
compatibility[:incompatible] = phs - compatibility[:compatible]
|
172
|
+
|
173
|
+
compatibility
|
174
|
+
end
|
175
|
+
|
121
176
|
def build_off_holiday(date_range)
|
122
177
|
start_year = date_range.wide_interval.start&.key?(:year) ? date_range.wide_interval.start[:year] : date_range.wide_interval.start
|
123
178
|
end_year = date_range.wide_interval.end&.key?(:year) ? date_range.wide_interval.end[:year] : date_range.wide_interval.end
|
@@ -135,9 +190,15 @@ module OpeningHoursConverter
|
|
135
190
|
def build_holiday(date_range)
|
136
191
|
start_year = date_range.wide_interval.start&.key?(:year) ? date_range.wide_interval.start[:year] : date_range.wide_interval.start
|
137
192
|
end_year = date_range.wide_interval.end&.key?(:year) ? date_range.wide_interval.end[:year] : date_range.wide_interval.end
|
138
|
-
|
139
193
|
intervals = date_range.typical.get_intervals(true)
|
140
|
-
|
194
|
+
|
195
|
+
if date_range.wide_interval.type == 'week'
|
196
|
+
intervals.each do |interval|
|
197
|
+
date_range.typical.add_interval(OpeningHoursConverter::Interval.new(-2, interval.start, -2, interval.end, interval.is_off))
|
198
|
+
end
|
199
|
+
else
|
200
|
+
date_range = OpeningHoursConverter::DateRange.new(OpeningHoursConverter::WideInterval.new.holiday('PH', start_year, end_year))
|
201
|
+
end
|
141
202
|
|
142
203
|
for i in 0..6
|
143
204
|
intervals.each do |interval|
|
@@ -156,7 +217,6 @@ module OpeningHoursConverter
|
|
156
217
|
rule.is_defined_off = rule.is_defined_off || interval.is_off
|
157
218
|
end
|
158
219
|
end
|
159
|
-
|
160
220
|
[rule]
|
161
221
|
end
|
162
222
|
|
@@ -327,6 +387,7 @@ module OpeningHoursConverter
|
|
327
387
|
|
328
388
|
def create_time_intervals(wide_interval, intervals)
|
329
389
|
days = []
|
390
|
+
|
330
391
|
for i in 0...7
|
331
392
|
days << OpeningHoursConverter::OpeningHoursRule.new
|
332
393
|
days[i].add_date(OpeningHoursConverter::OpeningHoursDate.new(wide_interval, [i]))
|
@@ -109,7 +109,7 @@ module OpeningHoursConverter
|
|
109
109
|
end
|
110
110
|
|
111
111
|
def add_overwritten_weekday(weekday)
|
112
|
-
return if @weekdays_over.include?(weekday)
|
112
|
+
return if @weekdays_over.include?(weekday)
|
113
113
|
|
114
114
|
@weekdays_over << weekday
|
115
115
|
@weekdays_over.sort!
|
@@ -1,23 +1,31 @@
|
|
1
1
|
require 'opening_hours_converter/constants'
|
2
|
+
require 'opening_hours_converter/utils'
|
2
3
|
require 'json'
|
3
4
|
|
4
5
|
module OpeningHoursConverter
|
5
6
|
class OpeningHoursParser
|
6
7
|
include Constants
|
8
|
+
include Utils
|
7
9
|
|
8
10
|
def initialize
|
9
11
|
@RGX_RULE_MODIFIER = /^(open|closed|off)$/i
|
10
12
|
@RGX_WEEK_KEY = /^week$/
|
11
|
-
@
|
13
|
+
@RGX_WEEK = /^week ([01234]?[0-9]|5[0123])(\-([01234]?[0-9]|5[0123]))?(, ?([01234]?[0-9]|5[0123])(\-([01234]?[0-9]|5[0123]))?)*$/
|
14
|
+
@RGX_WEEK_VAL = /^([01234]?[0-9]|5[0123])(\-([01234]?[0-9]|5[0123]))?(, ?([01234]?[0-9]|5[0123])(\-([01234]?[0-9]|5[0123]))?)*$/
|
15
|
+
@RGX_WEEK_WITH_MODIFIER = /^week ([01234]?[0-9]|5[0123])(\-([01234]?[0-9]|5[0123])(\/[1-9])?)?(, ?([01234]?[0-9]|5[0123])(\-([01234]?[0-9]|5[0123])(\/[1-9])?)?)*$/
|
16
|
+
@RGX_WEEK_VAL_WITH_MODIFIER = /^([01234]?[0-9]|5[0123])(\-([01234]?[0-9]|5[0123])(\/[1-9])?)?(, ?([01234]?[0-9]|5[0123])(\-([01234]?[0-9]|5[0123])(\/[1-9])?)?)*$/
|
12
17
|
@RGX_MONTH = /^(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)(\-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec))?\:?$/
|
13
18
|
@RGX_MONTHDAY = /^(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) ([012]?[0-9]|3[01])(\-((Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) )?([012]?[0-9]|3[01]))?\:?$/
|
14
19
|
@RGX_TIME = /^((([01]?[0-9]|2[01234])\:[012345][0-9](\-([01]?[0-9]|2[01234])\:[012345][0-9])?(,([01]?[0-9]|2[01234])\:[012345][0-9](\-([01]?[0-9]|2[01234])\:[012345][0-9])?)*)|(24\/7))$/
|
15
20
|
@RGX_WEEKDAY = /^(((Mo|Tu|We|Th|Fr|Sa|Su)(\-(Mo|Tu|We|Th|Fr|Sa|Su))?)|(PH))(,(((Mo|Tu|We|Th|Fr|Sa|Su)(\-(Mo|Tu|We|Th|Fr|Sa|Su))?)|(PH)))*$/
|
16
21
|
@RGX_HOLIDAY = /^(PH|SH|easter)$/
|
17
22
|
@RGX_WD = /^(Mo|Tu|We|Th|Fr|Sa|Su)(\-(Mo|Tu|We|Th|Fr|Sa|Su))?$/
|
23
|
+
@RGX_WD_WITH_MODIFIER = /^(Mo|Tu|We|Th|Fr|Sa|Su)\[([1-5]|\-1)\]$/
|
18
24
|
@RGX_DAY = /^([012]?[0-9]|3[01])(\-[012]?[0-9]|3[01])?$/
|
19
25
|
@RGX_YEAR = /^(\d{4})(\-(\d{4}))?$/
|
20
26
|
@RGX_YEAR_PH = /^(\d{4})( PH|(\-(\d{4}) PH))\:?$/
|
27
|
+
@RGX_YEAR_WEEK = /^(\d{4})(\-(\d{4}))? week ([01234]?[0-9]|5[0123])(\-([01234]?[0-9]|5[0123]))?(, ?([01234]?[0-9]|5[0123])(\-([01234]?[0-9]|5[0123]))?)*\:?$/
|
28
|
+
@RGX_YEAR_WEEK_WITH_MODIFIER = /^(\d{4})(\-(\d{4}))? week ([01234]?[0-9]|5[0123])(\-([01234]?[0-9]|5[0123])(\/[1-9])?)?(, ?([01234]?[0-9]|5[0123])(\-([01234]?[0-9]|5[0123])(\/[1-9])?)?)*$/
|
21
29
|
@RGX_YEAR_MONTH_DAY = /^(\d{4}) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) ([012]?[0-9]|3[01])(\-((\d{4}) )?((Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) )?([012]?[0-9]|3[01]))?\:?$/
|
22
30
|
@RGX_YEAR_MONTH = /^(\d{4}) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)(\-((\d{4}) )?((Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)))?\:?$/
|
23
31
|
@RGX_COMMENT = /^\"[^\"]*\"$/
|
@@ -45,7 +53,9 @@ module OpeningHoursConverter
|
|
45
53
|
block.strip!
|
46
54
|
next if block.empty?
|
47
55
|
|
48
|
-
|
56
|
+
tokenizer = OpeningHoursConverter::Tokenizer.new(block)
|
57
|
+
tokens = tokenizer.tokens
|
58
|
+
# tokens = tokenize(block)
|
49
59
|
@current_token = tokens.length - 1
|
50
60
|
|
51
61
|
weekdays = {}
|
@@ -66,9 +76,9 @@ module OpeningHoursConverter
|
|
66
76
|
weekday_selector = tokens[@current_token]
|
67
77
|
weekdays_and_holidays = get_weekdays(weekday_selector)
|
68
78
|
rescue StandardError
|
69
|
-
weekdays[[{ from: 0, to: 6 }]] ||= {}
|
70
|
-
weekdays[[{ from: 0, to: 6 }]][:modifiers] ||= []
|
71
|
-
weekdays[[{ from: 0, to: 6 }]][:modifiers] << local_modifier
|
79
|
+
weekdays[[{ from: 0, to: 6, index: nil }]] ||= {}
|
80
|
+
weekdays[[{ from: 0, to: 6, index: nil }]][:modifiers] ||= []
|
81
|
+
weekdays[[{ from: 0, to: 6, index: nil }]][:modifiers] << local_modifier
|
72
82
|
else
|
73
83
|
weekdays[weekdays_and_holidays] ||= {}
|
74
84
|
weekdays[weekdays_and_holidays][:modifiers] ||= []
|
@@ -86,9 +96,9 @@ module OpeningHoursConverter
|
|
86
96
|
weekday_selector = tokens[@current_token]
|
87
97
|
weekdays_and_holidays = get_weekdays(weekday_selector)
|
88
98
|
rescue StandardError
|
89
|
-
weekdays[[{ from: 0, to: 6 }]] ||= {}
|
90
|
-
weekdays[[{ from: 0, to: 6 }]][:times] ||= []
|
91
|
-
weekdays[[{ from: 0, to: 6 }]][:times].concat(local_times)
|
99
|
+
weekdays[[{ from: 0, to: 6, index: nil }]] ||= {}
|
100
|
+
weekdays[[{ from: 0, to: 6, index: nil }]][:times] ||= []
|
101
|
+
weekdays[[{ from: 0, to: 6, index: nil }]][:times].concat(local_times)
|
92
102
|
else
|
93
103
|
weekdays[weekdays_and_holidays] ||= {}
|
94
104
|
weekdays[weekdays_and_holidays][:times] ||= []
|
@@ -98,6 +108,7 @@ module OpeningHoursConverter
|
|
98
108
|
end
|
99
109
|
end
|
100
110
|
|
111
|
+
weeks = []
|
101
112
|
months = []
|
102
113
|
years = []
|
103
114
|
holidays = []
|
@@ -108,21 +119,27 @@ module OpeningHoursConverter
|
|
108
119
|
end
|
109
120
|
if !wide_range_selector.empty?
|
110
121
|
wide_range_selector = wide_range_selector.strip
|
111
|
-
wide_range_selector = wide_range_selector.split(',')
|
112
|
-
wide_range_selector.
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
122
|
+
# wide_range_selector = wide_range_selector.split(',')
|
123
|
+
if !(@RGX_YEAR_MONTH_DAY =~ wide_range_selector).nil?
|
124
|
+
years << get_year_month_day(wide_range_selector)
|
125
|
+
elsif !(@RGX_YEAR_MONTH =~ wide_range_selector).nil?
|
126
|
+
years << get_year_month(wide_range_selector)
|
127
|
+
elsif !(@RGX_MONTHDAY =~ wide_range_selector).nil?
|
128
|
+
months << get_month_day(wide_range_selector)
|
129
|
+
elsif !(@RGX_MONTH =~ wide_range_selector).nil?
|
130
|
+
months << get_month(wide_range_selector)
|
131
|
+
elsif !(@RGX_YEAR =~ wide_range_selector).nil?
|
132
|
+
years << get_year(wide_range_selector)
|
133
|
+
elsif !(@RGX_YEAR_WEEK_WITH_MODIFIER =~ wide_range_selector).nil?
|
134
|
+
weeks << get_year_week_with_modifier(wide_range_selector)
|
135
|
+
elsif !(@RGX_YEAR_WEEK =~ wide_range_selector).nil?
|
136
|
+
weeks << get_year_week(wide_range_selector)
|
137
|
+
elsif !(@RGX_WEEK_WITH_MODIFIER =~ wide_range_selector).nil?
|
138
|
+
weeks << get_week_with_modifier(wide_range_selector)
|
139
|
+
elsif !(@RGX_WEEK =~ wide_range_selector).nil?
|
140
|
+
weeks << get_week(wide_range_selector)
|
141
|
+
else
|
142
|
+
raise ArgumentError, "Unsupported selector #{wide_range_selector}"
|
126
143
|
end
|
127
144
|
end
|
128
145
|
end
|
@@ -130,6 +147,7 @@ module OpeningHoursConverter
|
|
130
147
|
raise ArgumentError, 'Unreadable string' if @current_token == tokens.length - 1
|
131
148
|
|
132
149
|
# puts "weekdays : #{weekdays}"
|
150
|
+
# puts "weeks : #{weeks}"
|
133
151
|
# puts "months : #{months}"
|
134
152
|
# puts "years : #{years}"
|
135
153
|
|
@@ -152,6 +170,12 @@ module OpeningHoursConverter
|
|
152
170
|
end
|
153
171
|
date_ranges << date_range
|
154
172
|
end
|
173
|
+
elsif !weeks.empty?
|
174
|
+
|
175
|
+
weeks.each do |week|
|
176
|
+
date_ranges << OpeningHoursConverter::WideInterval.new.week(week[:week_indexes], week[:year_from], week[:year_to])
|
177
|
+
end
|
178
|
+
|
155
179
|
elsif !years.empty?
|
156
180
|
years.each do |year|
|
157
181
|
if !year[:from_day].nil?
|
@@ -182,8 +206,8 @@ module OpeningHoursConverter
|
|
182
206
|
end
|
183
207
|
|
184
208
|
if weekdays.empty?
|
185
|
-
weekdays[[{ from: 0, to: 6 }]] = {}
|
186
|
-
weekdays[[{ from: 0, to: 6 }]][:times] = [{ from: 0, to: 24 * 60 }]
|
209
|
+
weekdays[[{ from: 0, to: 6, index: nil }]] = {}
|
210
|
+
weekdays[[{ from: 0, to: 6, index: nil }]][:times] = [{ from: 0, to: 24 * 60 }]
|
187
211
|
end
|
188
212
|
|
189
213
|
date_ranges.each do |dr|
|
@@ -280,7 +304,14 @@ module OpeningHoursConverter
|
|
280
304
|
if end_interval.day == start_interval.day + 1 && end_interval.hour == 0 && end_interval.min == 0
|
281
305
|
end_interval -= (1 / 1440.0)
|
282
306
|
end
|
283
|
-
date_range.last.typical.add_interval(
|
307
|
+
date_range.last.typical.add_interval(
|
308
|
+
OpeningHoursConverter::Interval.new(
|
309
|
+
reindex_sunday_week_to_monday_week(start_interval.wday),
|
310
|
+
(start_interval.hour * 60 + start_interval.min),
|
311
|
+
reindex_sunday_week_to_monday_week(end_interval.wday),
|
312
|
+
(end_interval.hour * 60 + end_interval.min)
|
313
|
+
)
|
314
|
+
)
|
284
315
|
end
|
285
316
|
end
|
286
317
|
date_range
|
@@ -300,6 +331,86 @@ module OpeningHoursConverter
|
|
300
331
|
{ from: year_from, to: year_to }
|
301
332
|
end
|
302
333
|
|
334
|
+
def get_year_week_with_modifier(wrs)
|
335
|
+
year, weeks = wrs.split(' week ')
|
336
|
+
years = year.split('-')
|
337
|
+
|
338
|
+
indexes = weeks.split(',').map { |week_index|
|
339
|
+
if week_index.include?('-')
|
340
|
+
if week_index.include?('/')
|
341
|
+
from, to = week_index.split('-')
|
342
|
+
to, modifier = to.split('/')
|
343
|
+
{ from: from.to_i, to: to.to_i, modifier: modifier.to_i }
|
344
|
+
else
|
345
|
+
from, to = week_index.split('-').map(&:to_i)
|
346
|
+
{ from: from, to: to }
|
347
|
+
end
|
348
|
+
else
|
349
|
+
week_index.to_i
|
350
|
+
end
|
351
|
+
}
|
352
|
+
|
353
|
+
{ year_from: years[0].to_i, week_indexes: indexes }.tap do |hsh|
|
354
|
+
hsh[:year_to] = years.length > 1 ? years[1].to_i : nil
|
355
|
+
end
|
356
|
+
end
|
357
|
+
|
358
|
+
def get_year_week(wrs)
|
359
|
+
year, weeks = wrs.split(' week ')
|
360
|
+
# does not handle 2018,2019
|
361
|
+
years = year.split('-')
|
362
|
+
# does not handle week 1,2,3
|
363
|
+
indexes = weeks.split(',').map { |week_index|
|
364
|
+
if week_index.include?('-')
|
365
|
+
from, to = week_index.split('-').map(&:to_i)
|
366
|
+
{ from: from, to: to }
|
367
|
+
else
|
368
|
+
week_index.to_i
|
369
|
+
end
|
370
|
+
}
|
371
|
+
|
372
|
+
{ week_indexes: indexes, year_from: year[0].to_i }.tap do |hsh|
|
373
|
+
hsh[:year_to] = years.length > 1 ? year[1].to_i : nil
|
374
|
+
end
|
375
|
+
end
|
376
|
+
|
377
|
+
def get_week_with_modifier(wrs)
|
378
|
+
weeks = wrs.gsub('week ', '').split(',')
|
379
|
+
|
380
|
+
indexes = weeks.map { |week_index|
|
381
|
+
if week_index.include?('-')
|
382
|
+
if week_index.include?('/')
|
383
|
+
from, to = week_index.split('-')
|
384
|
+
to, modifier = to.split('/')
|
385
|
+
{ from: from.to_i, to: to.to_i, modifier: modifier.to_i }
|
386
|
+
else
|
387
|
+
from, to = week_index.split('-').map(&:to_i)
|
388
|
+
{ from: from, to: to }
|
389
|
+
end
|
390
|
+
else
|
391
|
+
week_index.to_i
|
392
|
+
end
|
393
|
+
}
|
394
|
+
|
395
|
+
{ week_indexes: indexes }
|
396
|
+
end
|
397
|
+
|
398
|
+
def get_week(wrs)
|
399
|
+
weeks = wrs.gsub('week ', '').split(',')
|
400
|
+
|
401
|
+
indexes = weeks.map { |week_index|
|
402
|
+
if week_index.include?('-')
|
403
|
+
from, to = week_index.split('-').map(&:to_i)
|
404
|
+
{ from: from, to: to }
|
405
|
+
else
|
406
|
+
week_index.to_i
|
407
|
+
end
|
408
|
+
}
|
409
|
+
|
410
|
+
{ week_indexes: indexes }
|
411
|
+
end
|
412
|
+
|
413
|
+
|
303
414
|
def get_month(wrs)
|
304
415
|
single_month = wrs.gsub(/\:$/, '').split('-')
|
305
416
|
month_from = OSM_MONTHS.find_index(single_month[0]) + 1
|
@@ -429,9 +540,10 @@ module OpeningHoursConverter
|
|
429
540
|
wd_to = nil
|
430
541
|
|
431
542
|
weekday_selector = weekday_selector.split(',')
|
543
|
+
|
432
544
|
weekday_selector.each do |wd|
|
433
545
|
if !(@RGX_HOLIDAY =~ wd).nil?
|
434
|
-
weekdays << { from: -2, to: -2 }
|
546
|
+
weekdays << { from: -2, to: -2, index: nil }
|
435
547
|
elsif !(@RGX_WD =~ wd).nil?
|
436
548
|
single_weekday = wd.split('-')
|
437
549
|
|
@@ -442,7 +554,16 @@ module OpeningHoursConverter
|
|
442
554
|
wd_from
|
443
555
|
end
|
444
556
|
|
445
|
-
weekdays << { from: wd_from, to: wd_to }
|
557
|
+
weekdays << { from: wd_from, to: wd_to, index: nil }
|
558
|
+
elsif !(@RGX_WD_WITH_MODIFIER =~ wd).nil?
|
559
|
+
|
560
|
+
from, to = wd[0...wd.index('[')].split('-')
|
561
|
+
index = wd[wd.index('[') + 1...wd.index(']')]
|
562
|
+
|
563
|
+
wd_from = OSM_DAYS.find_index(from)
|
564
|
+
wd_to = OSM_DAYS.find_index(to)
|
565
|
+
|
566
|
+
weekdays << { from: wd_from, to: wd_from, index: index.to_i }
|
446
567
|
else
|
447
568
|
raise ArgumentError, "Invalid weekday interval : #{wd}"
|
448
569
|
end
|
@@ -564,6 +685,7 @@ module OpeningHoursConverter
|
|
564
685
|
weekday_merge = []
|
565
686
|
wide_interval_merge = []
|
566
687
|
merged_wide_interval = []
|
688
|
+
|
567
689
|
groups.each_with_index do |group, group_index|
|
568
690
|
if !wide_interval_merge.empty?
|
569
691
|
merged_wide_interval += [wide_interval_merge.join(' ')]
|
@@ -575,7 +697,7 @@ module OpeningHoursConverter
|
|
575
697
|
wide_interval_merge = []
|
576
698
|
new_tokens << merged_wide_interval.join(',')
|
577
699
|
end
|
578
|
-
if is_weekday?(token)
|
700
|
+
if is_weekday?(token) || is_weekday_with_modifier?(token)
|
579
701
|
weekday_merge << token
|
580
702
|
if token_index == group.length - 1 && group_index == groups.length - 1
|
581
703
|
new_tokens << weekday_merge.join(',')
|
@@ -606,7 +728,10 @@ module OpeningHoursConverter
|
|
606
728
|
def is_part_of_wide_interval?(string)
|
607
729
|
is_wide_interval = false
|
608
730
|
string.split('-').each do |str|
|
609
|
-
if (!(@RGX_YEAR =~ str).nil? || !(@RGX_YEAR_MONTH =~ str).nil? || !(@RGX_YEAR_MONTH_DAY =~ str).nil? ||
|
731
|
+
if (!(@RGX_YEAR =~ str).nil? || !(@RGX_YEAR_MONTH =~ str).nil? || !(@RGX_YEAR_MONTH_DAY =~ str).nil? ||
|
732
|
+
!(@RGX_DAY =~ str).nil? || !(@RGX_MONTHDAY =~ str).nil? || !(@RGX_MONTH =~ str).nil? ||
|
733
|
+
!(@RGX_WEEK_KEY =~ str).nil? || !(@RGX_WEEK_VAL =~ str).nil? || !(@RGX_WEEK_VAL_WITH_MODIFIER =~ str).nil?) &&
|
734
|
+
((@RGX_TIME =~ str).nil? && (@RGX_WEEKDAY =~ str).nil?)
|
610
735
|
is_wide_interval = true
|
611
736
|
else
|
612
737
|
return false
|
@@ -635,8 +760,38 @@ module OpeningHoursConverter
|
|
635
760
|
!(@RGX_WEEKDAY =~ token).nil?
|
636
761
|
end
|
637
762
|
|
763
|
+
def is_weekday_with_modifier?(token)
|
764
|
+
!(@RGX_WD_WITH_MODIFIER =~ token).nil?
|
765
|
+
end
|
766
|
+
|
638
767
|
def is_year?(token)
|
639
768
|
!(@RGX_YEAR =~ token).nil?
|
640
769
|
end
|
770
|
+
|
771
|
+
def is_week_key?(token)
|
772
|
+
!(@RGX_WEEK_KEY =~ token).nil?
|
773
|
+
end
|
774
|
+
|
775
|
+
def is_week_val?(token)
|
776
|
+
!(@RGX_WEEK_VAL =~ token).nil?
|
777
|
+
end
|
778
|
+
|
779
|
+
def is_week_with_modifier?(token)
|
780
|
+
!(@RGX_WEEK_WITH_MODIFIER =~ token).nil?
|
781
|
+
end
|
782
|
+
|
783
|
+
def is_week_val_with_modifier?(token)
|
784
|
+
!(@RGX_WEEK_VAL_WITH_MODIFIER =~ token).nil?
|
785
|
+
end
|
786
|
+
|
787
|
+
def is_year_week?(token)
|
788
|
+
!(@RGX_YEAR_WEEK =~ token).nil?
|
789
|
+
end
|
790
|
+
|
791
|
+
def is_year_week_with_modifier?(token)
|
792
|
+
!(@RGX_YEAR_WEEK_WITH_MODIFIER =~ token).nil?
|
793
|
+
end
|
641
794
|
end
|
642
795
|
end
|
796
|
+
|
797
|
+
|
@@ -61,6 +61,8 @@ module OpeningHoursConverter
|
|
61
61
|
month_start = -1
|
62
62
|
day_start = -1
|
63
63
|
|
64
|
+
return result_to_string(years) if is_only_week_interval?(years)
|
65
|
+
|
64
66
|
result = {}
|
65
67
|
|
66
68
|
if !years['always'].nil?
|
@@ -120,7 +122,7 @@ module OpeningHoursConverter
|
|
120
122
|
{ day: 30, month: 11 }
|
121
123
|
else
|
122
124
|
{ day: MONTH_END_DAY[month - 1] - 1, month: month - 1 }
|
123
|
-
|
125
|
+
end
|
124
126
|
else
|
125
127
|
{ day: day - 1, month: month }
|
126
128
|
end
|
@@ -148,63 +150,90 @@ module OpeningHoursConverter
|
|
148
150
|
|
149
151
|
def result_to_string(result)
|
150
152
|
str_result = ''
|
151
|
-
result
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
if is_same_day?(interval)
|
162
|
-
str_result += "#{OSM_MONTHS[interval[:start][:month]]} #{interval[:start][:day] + 1 < 10 ? "0#{interval[:start][:day] + 1}" : interval[:start][:day] + 1}"
|
153
|
+
if is_only_week_interval?(result)
|
154
|
+
local_str = result.keys == ['always'] ? 'week ' : result.keys.length == 1 ? result.keys.first.to_s + ' week ' : result.keys.min.to_s + '-' + result.keys.max.to_s + ' week '
|
155
|
+
|
156
|
+
intervals = result[result.keys.first]
|
157
|
+
intervals.each do |interval|
|
158
|
+
local_str += "," if !(local_str[local_str.length - 1] =~ /^[0-9]$/).nil?
|
159
|
+
local_str +=
|
160
|
+
if interval[:modifier].nil?
|
161
|
+
if interval[:start][:week] == interval[:end][:week]
|
162
|
+
interval[:start][:week].to_s
|
163
163
|
else
|
164
|
-
|
164
|
+
"#{interval[:start][:week].to_s + '-' + interval[:end][:week].to_s}"
|
165
165
|
end
|
166
166
|
else
|
167
|
-
|
167
|
+
"#{interval[:start][:week].to_s + '-' + interval[:end][:week].to_s}/#{interval[:modifier].to_s}"
|
168
168
|
end
|
169
|
-
|
170
|
-
|
171
|
-
|
169
|
+
end
|
170
|
+
str_result += local_str
|
171
|
+
else
|
172
|
+
result.each do |selector, intervals|
|
173
|
+
if selector == 'always'
|
172
174
|
intervals.each do |interval|
|
173
175
|
str_result += ',' if !str_result.empty?
|
174
|
-
if
|
176
|
+
if is_full_year?(interval)
|
177
|
+
elsif starts_year?(interval) && ends_year?(interval)
|
175
178
|
str_result += "#{interval[:start][:year]}-#{interval[:end][:year]}"
|
176
|
-
|
177
|
-
|
179
|
+
elsif is_full_month?(interval)
|
180
|
+
str_result += (OSM_MONTHS[interval[:start][:month]]).to_s
|
181
|
+
elsif is_same_month?(interval)
|
182
|
+
if is_same_day?(interval)
|
183
|
+
str_result += "#{OSM_MONTHS[interval[:start][:month]]} #{interval[:start][:day] + 1 < 10 ? "0#{interval[:start][:day] + 1}" : interval[:start][:day] + 1}"
|
184
|
+
else
|
185
|
+
str_result += "#{OSM_MONTHS[interval[:start][:month]]} #{interval[:start][:day] + 1 < 10 ? "0#{interval[:start][:day] + 1}" : interval[:start][:day] + 1}-#{interval[:end][:day] + 1 < 10 ? "0#{interval[:end][:day] + 1}" : interval[:end][:day] + 1}"
|
186
|
+
end
|
187
|
+
elsif starts_month?(interval) && ends_month?(interval)
|
188
|
+
str_result += "#{OSM_MONTHS[interval[:start][:month]]}-#{OSM_MONTHS[interval[:end][:month]]}"
|
178
189
|
else
|
179
|
-
str_result += "#{
|
190
|
+
str_result += "#{OSM_MONTHS[interval[:start][:month]]} #{interval[:start][:day] + 1 < 10 ? "0#{interval[:start][:day] + 1}" : interval[:start][:day] + 1}-#{OSM_MONTHS[interval[:end][:month]]} #{interval[:end][:day] + 1 < 10 ? "0#{interval[:end][:day] + 1}" : interval[:end][:day] + 1}"
|
180
191
|
end
|
181
192
|
end
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
193
|
+
elsif selector == 'multi_year'
|
194
|
+
intervals.each do |_years, intervals|
|
195
|
+
intervals.each do |interval|
|
196
|
+
str_result += ',' if !str_result.empty?
|
197
|
+
if starts_year?(interval) && ends_year?(interval)
|
198
|
+
str_result += "#{interval[:start][:year]}-#{interval[:end][:year]}"
|
199
|
+
else
|
200
|
+
str_result += "#{interval[:start][:year]} #{OSM_MONTHS[interval[:start][:month]]} #{interval[:start][:day] + 1 < 10 ? "0#{interval[:start][:day] + 1}" : interval[:start][:day] + 1}-#{interval[:end][:year]} #{OSM_MONTHS[interval[:end][:month]]} #{interval[:end][:day] + 1 < 10 ? "0#{interval[:end][:day] + 1}" : interval[:end][:day] + 1}"
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
204
|
+
else
|
205
|
+
local_str = "#{selector} "
|
206
|
+
intervals.each do |interval|
|
207
|
+
if is_full_year?(interval)
|
208
|
+
elsif is_same_month?(interval)
|
209
|
+
if is_same_day?(interval)
|
210
|
+
local_str += "#{local_str.length > 5 ? ',' : ''}#{OSM_MONTHS[interval[:start][:month]]} #{interval[:start][:day] + 1 < 10 ? "0#{interval[:start][:day] + 1}" : interval[:start][:day] + 1}"
|
211
|
+
else
|
212
|
+
local_str += "#{local_str.length > 5 ? ',' : ''}#{OSM_MONTHS[interval[:start][:month]]} #{interval[:start][:day] + 1 < 10 ? "0#{interval[:start][:day] + 1}" : interval[:start][:day] + 1}-#{interval[:end][:day] + 1 < 10 ? "0#{interval[:end][:day] + 1}" : interval[:end][:day] + 1}"
|
213
|
+
end
|
194
214
|
else
|
195
|
-
local_str += "#{local_str.length > 5 ? ',' : ''}#{OSM_MONTHS[interval[:start][:month]]} #{interval[:start][:day] + 1 < 10 ? "0#{interval[:start][:day] + 1}" : interval[:start][:day] + 1}-#{interval[:end][:day] + 1 < 10 ? "0#{interval[:end][:day] + 1}" : interval[:end][:day] + 1}"
|
215
|
+
local_str += "#{local_str.length > 5 ? ',' : ''}#{OSM_MONTHS[interval[:start][:month]]} #{interval[:start][:day] + 1 < 10 ? "0#{interval[:start][:day] + 1}" : interval[:start][:day] + 1}-#{selector} #{OSM_MONTHS[interval[:end][:month]]} #{interval[:end][:day] + 1 < 10 ? "0#{interval[:end][:day] + 1}" : interval[:end][:day] + 1}"
|
196
216
|
end
|
197
|
-
|
198
|
-
local_str += "#{local_str.length > 5 ? ',' : ''}#{OSM_MONTHS[interval[:start][:month]]} #{interval[:start][:day] + 1 < 10 ? "0#{interval[:start][:day] + 1}" : interval[:start][:day] + 1}-#{selector} #{OSM_MONTHS[interval[:end][:month]]} #{interval[:end][:day] + 1 < 10 ? "0#{interval[:end][:day] + 1}" : interval[:end][:day] + 1}"
|
217
|
+
str_result += "#{!str_result.empty? ? ',' : ''}#{local_str}"
|
199
218
|
end
|
200
219
|
end
|
201
|
-
str_result += "#{!str_result.empty? ? ',' : ''}#{local_str}"
|
202
220
|
end
|
203
221
|
end
|
204
222
|
|
205
223
|
str_result.strip
|
206
224
|
end
|
207
225
|
|
226
|
+
def is_only_week_interval?(r)
|
227
|
+
r.all? do |year, intervals|
|
228
|
+
intervals.all? do |interval|
|
229
|
+
is_week_interval?(interval)
|
230
|
+
end
|
231
|
+
end
|
232
|
+
end
|
233
|
+
def is_week_interval?(interval)
|
234
|
+
!interval.is_a?(Array) && interval.key?(:start) && interval[:start].key?(:week)
|
235
|
+
end
|
236
|
+
|
208
237
|
def is_full_year?(r)
|
209
238
|
starts_year?(r) && ends_year?(r)
|
210
239
|
end
|
@@ -3,11 +3,12 @@ require 'opening_hours_converter/constants'
|
|
3
3
|
module OpeningHoursConverter
|
4
4
|
class WideInterval
|
5
5
|
include Constants
|
6
|
-
attr_accessor :start, :end, :type
|
6
|
+
attr_accessor :start, :end, :type, :indexes
|
7
7
|
|
8
8
|
def initialize
|
9
9
|
@start = nil
|
10
10
|
@end = nil
|
11
|
+
@indexes = nil
|
11
12
|
@type = nil
|
12
13
|
end
|
13
14
|
|
@@ -87,13 +88,11 @@ module OpeningHoursConverter
|
|
87
88
|
'jours fériés'
|
88
89
|
else
|
89
90
|
"les jours fériés de #{@start[:year]} à #{@end[:year]}"
|
90
|
-
|
91
|
+
end
|
92
|
+
elsif !@start[:year]
|
93
|
+
'jours fériés'
|
91
94
|
else
|
92
|
-
|
93
|
-
'jours fériés'
|
94
|
-
else
|
95
|
-
"les jours fériés de #{@start[:year]}"
|
96
|
-
end
|
95
|
+
"les jours fériés de #{@start[:year]}"
|
97
96
|
end
|
98
97
|
when 'always'
|
99
98
|
result = 'tout le temps'
|
@@ -135,6 +134,17 @@ module OpeningHoursConverter
|
|
135
134
|
self
|
136
135
|
end
|
137
136
|
|
137
|
+
def week(week_indexes, start_year = nil, end_year = nil)
|
138
|
+
raise(ArgumentError, 'weeks are required (array of ints)') if week_indexes.nil? || !week_indexes.is_a?(Array)
|
139
|
+
@start = { year: start_year }
|
140
|
+
@indexes = week_indexes
|
141
|
+
if !start_year.nil? && !end_year.nil? && end_year != start_year
|
142
|
+
@end = { year: end_year }
|
143
|
+
end
|
144
|
+
@type = 'week'
|
145
|
+
self
|
146
|
+
end
|
147
|
+
|
138
148
|
def year(start_year, end_year = nil)
|
139
149
|
raise(ArgumentError, 'start_year is required') if start_year.nil?
|
140
150
|
@start = { year: start_year }
|
@@ -212,6 +222,17 @@ module OpeningHoursConverter
|
|
212
222
|
else
|
213
223
|
my = to_day
|
214
224
|
o = o.to_day
|
225
|
+
|
226
|
+
if my.is_a?(Array)
|
227
|
+
if o.is_a?(Array)
|
228
|
+
return false
|
229
|
+
else
|
230
|
+
return my.all? { |day| day.contains?(o) }
|
231
|
+
end
|
232
|
+
elsif o.is_a?(Array)
|
233
|
+
return o.all? { |day| contains?(day) }
|
234
|
+
end
|
235
|
+
|
215
236
|
result = has_superior_or_equal_start_day?(my, o) && has_inferior_or_equal_end_day?(my, o)
|
216
237
|
end
|
217
238
|
result
|
@@ -227,6 +248,22 @@ module OpeningHoursConverter
|
|
227
248
|
my = to_day
|
228
249
|
o = o.to_day
|
229
250
|
|
251
|
+
if my.is_a?(Array)
|
252
|
+
if o.is_a?(Array)
|
253
|
+
return my.any? do |day|
|
254
|
+
o.any? do |o_day|
|
255
|
+
day.touch?(o_day)
|
256
|
+
end
|
257
|
+
end
|
258
|
+
else
|
259
|
+
return my.any? { |day| day.touch?(o) }
|
260
|
+
end
|
261
|
+
elsif o.is_a?(Array)
|
262
|
+
return o.any? { |day| day.touch?(my) }
|
263
|
+
end
|
264
|
+
# solution poour les weeks, on peut convertir un wide interval week en array de wide interval days et comparer les wide interval week
|
265
|
+
# un par un (long si deux wide interval multiweek)
|
266
|
+
# problem : comment calculer les weeks always ? comparer sur l'année en cours si o est always, les années de o sinon
|
230
267
|
result = ((my_start_is_before_o_end?(my, o) && my_start_is_after_o_start?(my, o)) ||
|
231
268
|
(my_end_is_before_o_end?(my, o) && my_end_is_after_o_start?(my, o))) ||
|
232
269
|
((my_start_is_before_o_end?(o, my) && my_start_is_after_o_start?(o, my)) ||
|
@@ -390,10 +427,33 @@ module OpeningHoursConverter
|
|
390
427
|
o.start[:day] >= my.start[:day]))
|
391
428
|
end
|
392
429
|
|
430
|
+
def sort_days_array(days_array, by = :start)
|
431
|
+
if days_array.all? { |day| day.start && !day.start[:year].nil? }
|
432
|
+
days_array.sort_by { |day| [day.send(by)[:year], day.send(by)[:month], day.send(by)[:day]] }
|
433
|
+
else
|
434
|
+
days_array.sort_by { |day| [day.send(by)[:month], day.send(by)[:day]] }
|
435
|
+
end
|
436
|
+
|
437
|
+
end
|
438
|
+
|
393
439
|
def has_superior_or_equal_start_day?(my, o)
|
394
440
|
result = false
|
395
441
|
if has_start_year?(o) && has_start_year?(my)
|
396
|
-
|
442
|
+
if o.is_a?(Array)
|
443
|
+
if my.is_a?(Array)
|
444
|
+
o = sort_days_array o
|
445
|
+
my = sort_days_array my
|
446
|
+
has_superior_or_equal_start_day?(my.first, o.first)
|
447
|
+
else
|
448
|
+
o = sort_days_array o
|
449
|
+
has_superior_or_equal_start_day?(my, o.first)
|
450
|
+
end
|
451
|
+
elsif my.is_a?(Array)
|
452
|
+
my = sort_days_array my
|
453
|
+
has_superior_or_equal_start_day?(my.first, o)
|
454
|
+
else
|
455
|
+
result = o.start[:year] > my.start[:year] || (o.start[:year] == my.start[:year] && has_superior_start_month?(my, o))
|
456
|
+
end
|
397
457
|
elsif !has_start_year?(my)
|
398
458
|
result = has_superior_start_month?(my, o)
|
399
459
|
end
|
@@ -433,7 +493,11 @@ module OpeningHoursConverter
|
|
433
493
|
end
|
434
494
|
|
435
495
|
def has_start_year?(date)
|
436
|
-
|
496
|
+
if date.is_a?(Array)
|
497
|
+
date.all? { |d| !d.start[:year].nil? }
|
498
|
+
else
|
499
|
+
!date.start[:year].nil?
|
500
|
+
end
|
437
501
|
end
|
438
502
|
|
439
503
|
def has_end_year?(date)
|
@@ -450,6 +514,23 @@ module OpeningHoursConverter
|
|
450
514
|
return false if @type == 'always'
|
451
515
|
self_to_day = to_day
|
452
516
|
o_to_day = o.to_day
|
517
|
+
return false if self_to_day.is_a?(Array) != o_to_day.is_a?(Array)
|
518
|
+
|
519
|
+
if self_to_day.is_a?(Array)
|
520
|
+
if o_to_day.is_a?(Array)
|
521
|
+
return false unless o_to_day.length == self_to_day.length
|
522
|
+
return self_to_day.all? do |self_day|
|
523
|
+
o_to_day.any? do |o_day|
|
524
|
+
self_day.equals(o_day)
|
525
|
+
end
|
526
|
+
end
|
527
|
+
else
|
528
|
+
return self_to_day.all? { |day| self_to_day.equals(o_to_day) }
|
529
|
+
end
|
530
|
+
elsif o_to_day.is_a?(Array)
|
531
|
+
return o_to_day.all? { |day| equals(day) }
|
532
|
+
end
|
533
|
+
|
453
534
|
(self_to_day.start[:year] == o_to_day.start[:year] &&
|
454
535
|
self_to_day.start[:month] == o_to_day.start[:month] &&
|
455
536
|
self_to_day.start[:day] == o_to_day.start[:day]) &&
|
@@ -461,8 +542,11 @@ module OpeningHoursConverter
|
|
461
542
|
|
462
543
|
def width
|
463
544
|
return Float::INFINITY if @type == 'always'
|
545
|
+
|
464
546
|
in_day = to_day
|
465
547
|
days_count = 0
|
548
|
+
return in_day.map(&:width).sum if in_day.is_a?(Array)
|
549
|
+
|
466
550
|
if in_day.end
|
467
551
|
if in_day.start[:year] && in_day.end[:year]
|
468
552
|
if in_day.start[:year] != in_day.end[:year]
|
@@ -541,6 +625,7 @@ module OpeningHoursConverter
|
|
541
625
|
end
|
542
626
|
|
543
627
|
def to_day
|
628
|
+
# les semaines rentrent en opposition avec cette maniere de faire : il n'y a pas un debut et une fin il y en a plusieurs (1-53/2)
|
544
629
|
case @type
|
545
630
|
when 'day'
|
546
631
|
if @end.nil?
|
@@ -560,6 +645,70 @@ module OpeningHoursConverter
|
|
560
645
|
else
|
561
646
|
OpeningHoursConverter::WideInterval.new.day(1, 1, @start[:year], 31, 12, @end[:year])
|
562
647
|
end
|
648
|
+
when 'holiday'
|
649
|
+
if @start && @start[:year]
|
650
|
+
if @end && @end[:year]
|
651
|
+
weeks = []
|
652
|
+
(@start[:year]..@end[:year]).each do |year|
|
653
|
+
weeks += get_public_holidays_for_year(year)
|
654
|
+
end
|
655
|
+
weeks
|
656
|
+
else
|
657
|
+
get_public_holidays_for_year(@start[:year])
|
658
|
+
end
|
659
|
+
else
|
660
|
+
get_public_holidays_for_year
|
661
|
+
end
|
662
|
+
when 'week'
|
663
|
+
if @start && @start[:year]
|
664
|
+
if @end && @end[:year]
|
665
|
+
weeks = []
|
666
|
+
(@start[:year]..@end[:year]).each do |year|
|
667
|
+
weeks += get_weeks_for_year(year)
|
668
|
+
end
|
669
|
+
weeks
|
670
|
+
else
|
671
|
+
get_weeks_for_year(@start[:year])
|
672
|
+
end
|
673
|
+
else
|
674
|
+
get_weeks_for_year
|
675
|
+
end
|
676
|
+
end
|
677
|
+
end
|
678
|
+
|
679
|
+
def get_weeks_for_year(year = Time.now.year)
|
680
|
+
weeks_as_days = []
|
681
|
+
@indexes.each do |week_index|
|
682
|
+
if week_index.is_a?(Integer)
|
683
|
+
week = OpeningHoursConverter::WeekIndex.week_from_index(week_index, year)
|
684
|
+
weeks_as_days << OpeningHoursConverter::WideInterval.new.day(week[:from].day, week[:from].month, week[:from].year,
|
685
|
+
week[:to].day, week[:to].month, week[:to].year)
|
686
|
+
else
|
687
|
+
if week_index.key?(:modifier)
|
688
|
+
i = 0
|
689
|
+
(week_index[:from]..week_index[:to]).map do |index|
|
690
|
+
if i % week_index[:modifier] == 0
|
691
|
+
week = OpeningHoursConverter::WeekIndex.week_from_index(index, year)
|
692
|
+
weeks_as_days << OpeningHoursConverter::WideInterval.new.day(week[:from].day, week[:from].month, week[:from].year,
|
693
|
+
week[:to].day, week[:to].month, week[:to].year)
|
694
|
+
end
|
695
|
+
i += 1
|
696
|
+
end
|
697
|
+
else
|
698
|
+
(week_index[:from]..week_index[:to]).map do |index|
|
699
|
+
week = OpeningHoursConverter::WeekIndex.week_from_index(index, year)
|
700
|
+
weeks_as_days << OpeningHoursConverter::WideInterval.new.day(week[:from].day, week[:from].month, week[:from].year,
|
701
|
+
week[:to].day, week[:to].month, week[:to].year)
|
702
|
+
end
|
703
|
+
end
|
704
|
+
end
|
705
|
+
end
|
706
|
+
|
707
|
+
weeks_as_days
|
708
|
+
end
|
709
|
+
def get_public_holidays_for_year(year = Time.now.year)
|
710
|
+
OpeningHoursConverter::PublicHoliday.ph_for_year(year).map do |holiday|
|
711
|
+
OpeningHoursConverter::WideInterval.new.day(holiday.day, holiday.month, holiday.year)
|
563
712
|
end
|
564
713
|
end
|
565
714
|
end
|
@@ -82,7 +82,59 @@ module OpeningHoursConverter
|
|
82
82
|
def self.build_day_array_from_dates(dates, get_iterator=false)
|
83
83
|
years = {}
|
84
84
|
dates.each do |date|
|
85
|
-
|
85
|
+
|
86
|
+
if date.wide_interval.type == 'week'
|
87
|
+
if date.wide_interval.start.nil? || date.wide_interval.start[:year].nil?
|
88
|
+
date.wide_interval.indexes.each do |week_index|
|
89
|
+
if week_index.is_a? Integer
|
90
|
+
years["always"] ||= []
|
91
|
+
years["always"] << { start: { week: week_index }, end: { week: week_index } }
|
92
|
+
elsif week_index.is_a?(Hash) && week_index.key?(:modifier)
|
93
|
+
# week range with modifier
|
94
|
+
years["always"] ||= []
|
95
|
+
years["always"] << { start: { week: week_index[:from] }, end: { week: week_index[:to] }, modifier: week_index[:modifier] }
|
96
|
+
else
|
97
|
+
# week range
|
98
|
+
years["always"] ||= []
|
99
|
+
years["always"] << { start: { week: week_index[:from] }, end: { week: week_index[:to] } }
|
100
|
+
end
|
101
|
+
end
|
102
|
+
else
|
103
|
+
if date.wide_interval.end.nil? || date.wide_interval.end[:year].nil?
|
104
|
+
date.wide_interval.indexes.each do |week_index|
|
105
|
+
if week_index.is_a? Integer
|
106
|
+
years[date.wide_interval.start[:year]] ||= []
|
107
|
+
years[date.wide_interval.start[:year]] << { start: { week: week_index }, end: { week: week_index } }
|
108
|
+
elsif week_index.is_a?(Hash) && week_index.key?(:modifier)
|
109
|
+
# week range with modifier
|
110
|
+
years[date.wide_interval.start[:year]] ||= []
|
111
|
+
years[date.wide_interval.start[:year]] << { start: { week: week_index[:from] }, end: { week: week_index[:to] }, modifier: week_index[:modifier] }
|
112
|
+
else
|
113
|
+
# week range
|
114
|
+
years[date.wide_interval.start[:year]] ||= []
|
115
|
+
years[date.wide_interval.start[:year]] << { start: { week: week_index[:from] }, end: { week: week_index[:to] } }
|
116
|
+
end
|
117
|
+
end
|
118
|
+
else
|
119
|
+
date.wide_interval.start[:year].upto(date.wide_interval.end[:year]) do |year|
|
120
|
+
date.wide_interval.indexes.each do |week_index|
|
121
|
+
if week_index.is_a? Integer
|
122
|
+
years[year] ||= []
|
123
|
+
years[year] << { start: { week: week_index }, end: { week: week_index } }
|
124
|
+
elsif week_index.is_a?(Hash) && week_index.key?(:modifier)
|
125
|
+
# week range with modifier
|
126
|
+
years[year] ||= []
|
127
|
+
years[year] << { start: { week: week_index[:from] }, end: { week: week_index[:to] }, modifier: week_index[:modifier] }
|
128
|
+
else
|
129
|
+
# week range
|
130
|
+
years[year] ||= []
|
131
|
+
years[year] << { start: { week: week_index[:from] }, end: { week: week_index[:to] } }
|
132
|
+
end
|
133
|
+
end
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
elsif !date.wide_interval.start.nil? && !date.wide_interval.start[:year].nil?
|
86
138
|
if date.wide_interval.end.nil? || date.wide_interval.end[:year].nil? || date.wide_interval.start[:year] == date.wide_interval.end[:year]
|
87
139
|
if !years[date.wide_interval.start[:year]].nil?
|
88
140
|
years = process_single_year(date.wide_interval, years)
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: opening_hours_converter
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Ziserman Martin
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-05-
|
11
|
+
date: 2019-05-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: json
|
@@ -79,8 +79,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
79
79
|
- !ruby/object:Gem::Version
|
80
80
|
version: '0'
|
81
81
|
requirements: []
|
82
|
-
|
83
|
-
rubygems_version: 2.7.3
|
82
|
+
rubygems_version: 3.0.3
|
84
83
|
signing_key:
|
85
84
|
specification_version: 4
|
86
85
|
summary: Datetime range to openinghours, openinghours to datetime range
|