opening_hours_converter 1.3.1 → 1.3.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 702767227bb2f956ceddf4f0ca6c99352c6e1fea
4
- data.tar.gz: fa9efab32584b5cea03ccf9ffb94c143eefb91db
3
+ metadata.gz: f8e4e03653c0ff37b313eebc544293f0a94f8e64
4
+ data.tar.gz: d5d03ad9394c9fad99f378f5709c79bf511bcd0d
5
5
  SHA512:
6
- metadata.gz: 9beee7a6b16b7427d968435b79cba79b420802e17419cd3265b97860ccfe18d726816b5feb969e9f8e7bb20e5c2349315490ae69f32966b83ae593ee49494429
7
- data.tar.gz: e2faf52f40999e498772067bd5893a6986a2e90f9250b73eb65c0fd7ababbb7e93b9d4a51b8898cdb9b6a2c598dc84981e80cbe8e58eddc80077854124a6c345
6
+ metadata.gz: d3c40e4249a5d4ad180fc57f0a570278d12154b572332de6c623c442f70304fa8670ebe2079bd707d4597a213692f959f67a33d702034f7cd782a74e8ba74914
7
+ data.tar.gz: 6637cfb3f4a33c807247cf7589ce2da1f43bca1848e816e4af10ca88b8f8c26ad526d3f5a3767d367b7bc5a9422fba756542a6fb1219bf4f2b37502efcec9e81
@@ -0,0 +1,176 @@
1
+ require 'opening_hours_converter/constants'
2
+ require 'pry-nav'
3
+ module OpeningHoursConverter
4
+ class Iterator
5
+ include Constants
6
+
7
+ def get_iterator(date_ranges)
8
+ date_ranges_array = []
9
+ years = nil
10
+
11
+ date_ranges.each do |date_range|
12
+ years = OpeningHoursConverter::Year.build_day_array_from_date_range(date_range, true)
13
+ result = []
14
+
15
+ year_start = -1
16
+ month_start = -1
17
+ day_start = -1
18
+
19
+ years.each do |year, months|
20
+ months.each_with_index do |month_array, month|
21
+ month_array.each_with_index do |day_bool, day|
22
+ if day_bool && year_start < 0
23
+ year_start = year
24
+ month_start = month
25
+ day_start = day
26
+ elsif day_bool && year_start >= 0 && month == 11 && day == 30 && years[year+1].nil?
27
+
28
+ result << { start: DateTime.new(year_start, month_start+1, day_start+1), end: DateTime.new(year, 12, 31)}
29
+
30
+ year_start = -1
31
+ month_start = -1
32
+ day_start = -1
33
+ elsif !day_bool && year_start >= 0
34
+ end_res = {}
35
+
36
+ if day == 0
37
+ if month == 0
38
+ end_res = DateTime.new(year-1, 12, 31)
39
+ else
40
+ end_res = DateTime.new(year, month, MONTH_END_DAY[month])
41
+ end
42
+ else
43
+
44
+ end_res = DateTime.new(year, month+1, day)
45
+ end
46
+
47
+ result << { start: DateTime.new(year_start, month_start+1, day_start+1), end: end_res }
48
+ year_start = -1
49
+ month_start = -1
50
+ day_start = -1
51
+ end
52
+ end
53
+ end
54
+ end
55
+
56
+ date_ranges_array << result
57
+ end
58
+
59
+
60
+ return date_ranges_array
61
+ end
62
+
63
+ def get_time_iterator(date_ranges)
64
+ # binding.pry
65
+ is_ph = false
66
+ year = nil
67
+ year_ph = nil
68
+ date_ranges.each do |dr|
69
+ is_ph = true if dr.is_holiday?
70
+ end
71
+ date_ranges_array = get_iterator(date_ranges)
72
+ datetime_result = []
73
+
74
+
75
+ date_ranges_array.each_with_index do |result, index|
76
+ result.each do |interval|
77
+ (interval[:start]..interval[:end]).each do |day|
78
+ if year != day.year && is_ph
79
+ year = day.year
80
+ year_ph = PublicHoliday.ph_for_year(year)
81
+ end
82
+ date_ranges[index].typical.intervals.each do |i|
83
+ if !i.nil?
84
+ if (i.day_start..i.day_end).include?(fix_datetime_wday(day.wday)) || (is_ph && year_ph.include?(Time.new(day.year, day.month, day.day)))
85
+ itr = { start: Time.new(day.year, day.month, day.day, i.start/60, i.start%60),
86
+ end: Time.new(day.year, day.month, day.day, i.end/60, i.end%60) }
87
+ datetime_result << itr unless datetime_result.include?(itr)
88
+ end
89
+ end
90
+ end
91
+ end
92
+ end
93
+ end
94
+
95
+ datetime_result.sort {|a,b| a[:start] <=> b[:start]}
96
+
97
+ end
98
+
99
+ def get_datetime_iterator(date_ranges)
100
+ result = get_iterator(date_ranges)
101
+ datetime_result = []
102
+
103
+ date_ranges_array.each_with_index do |result, index|
104
+ result.each do |interval|
105
+ (interval[:start]..interval[:end]).each do |day|
106
+ date_ranges[index].typical.intervals.each do |i|
107
+ if (i.day_start..i.day_end).include?(fix_datetime_wday(day.wday))
108
+ datetime_result << { start: DateTime.new(day.year, day.month, day.day, i.start/60, i.start%60),
109
+ end: DateTime.new(day.year, day.month, day.day, i.end/60, i.end%60) }
110
+ end
111
+ end
112
+ end
113
+ end
114
+ end
115
+
116
+ datetime_result.sort {|a,b| a[:start] <=> b[:start]}
117
+ end
118
+
119
+
120
+ def fix_datetime_wday(d)
121
+ d==0 ? 6 : d-1
122
+ end
123
+
124
+ # A partir d'une string OH et d'une DateTime (= now par défaut), renvoyer le current state (début / fin / commentaire)
125
+ def state(opening_hours_string, time=Time.now)
126
+ date_ranges = OpeningHoursConverter::OpeningHoursParser.new.parse(opening_hours_string)
127
+ ti = get_time_iterator(date_ranges)
128
+ ti.each do |interval|
129
+ return interval if interval[:start] <= time && interval[:end] >= time
130
+ end
131
+ return false
132
+ end
133
+
134
+ # A partir d'une string OH et d'une DateTime (= now par défaut), renvoyer le prochain state (début / fin / commentaire - nextState dans opening_hours.js) permettant d'afficher à l'utilisateur le prochain événement (ouverture/fermeture)
135
+ def next_state(opening_hours_string, time=Time.now)
136
+ date_ranges = OpeningHoursConverter::OpeningHoursParser.new.parse(opening_hours_string)
137
+ ti = get_time_iterator(date_ranges)
138
+ ti.each_with_index do |interval, index|
139
+ return {end: interval[:end]} if interval[:start] <= time && interval[:end] >= time
140
+ return {start: interval[:start]} if interval[:start] > time && ti[index-1][:end] <= time
141
+ end
142
+ return false
143
+ end
144
+
145
+
146
+ def next_period(opening_hours_string, time=Time.now)
147
+ date_ranges = OpeningHoursConverter::OpeningHoursParser.new.parse(opening_hours_string)
148
+ ti = get_time_iterator(date_ranges)
149
+ ti.each_with_index do |interval, index|
150
+ return ti[index+1] if interval[:start] <= time && interval[:end] >= time
151
+ return interval if interval[:start] > time && ti[index-1][:end] <= time
152
+ end
153
+ return false
154
+ end
155
+
156
+ # A partir d'une string OH et d'une DateTime (= now par défaut), déterminer cela correspond à une période d'ouverture : renvoyer un boolean.
157
+ def is_opened?(opening_hours_string, time=Time.now)
158
+ date_ranges = OpeningHoursConverter::OpeningHoursParser.new.parse(opening_hours_string)
159
+ ti = get_time_iterator(date_ranges)
160
+ ti.each do |interval|
161
+ return true if interval[:start] <= time && interval[:end] >= time
162
+ end
163
+ return false
164
+ end
165
+
166
+
167
+ def datetime_to_time(datetime)
168
+ Time.new(datetime.year, datetime.month, datetime.day, datetime.hour, datetime.min, datetime.sec, datetime.zone)
169
+ end
170
+
171
+ def time_to_datetime(time)
172
+ DateTime.new(time.year, time.month, time.day, time.hour, time.min, time.sec, Rational(time.gmt_offset / 3600, 24))
173
+ end
174
+
175
+ end
176
+ end
@@ -0,0 +1,320 @@
1
+ require 'opening_hours_converter/constants'
2
+
3
+ module OpeningHoursConverter
4
+ class Year
5
+ include Constants
6
+
7
+ def self.build_day_array_from_date_range(date_range, get_iterator=false)
8
+ years = {}
9
+ if date_range.is_holiday? && get_iterator
10
+ if date_range.wide_interval.type == "holiday"
11
+ if !date_range.wide_interval.start[:year].nil?
12
+ if !date_range.wide_interval.end.nil?
13
+ for year in date_range.wide_interval.start[:year]..date_range.wide_interval.end[:year]
14
+ years[year] ||= Array.new(OSM_MONTHS.length) { |i| Array.new(MONTH_END_DAY[i]) { false } }
15
+ end
16
+ years = process_holidays(date_range.wide_interval, years)
17
+ else
18
+ years[date_range.wide_interval.start[:year]] ||= Array.new(OSM_MONTHS.length) { |i| Array.new(MONTH_END_DAY[i]) { false } }
19
+ years = process_holidays(date_range.wide_interval, years)
20
+ end
21
+ else
22
+ remove_holiday!(date_range)
23
+
24
+ years = process_always_holiday(date_range.wide_interval, years)
25
+ end
26
+ else
27
+
28
+ end
29
+ end
30
+ if !date_range.wide_interval.start.nil? && !date_range.wide_interval.start[:year].nil?
31
+ if date_range.wide_interval.end.nil? || date_range.wide_interval.end[:year].nil? || date_range.wide_interval.start[:year] == date_range.wide_interval.end[:year]
32
+ if !years[date_range.wide_interval.start[:year]].nil?
33
+ years = process_single_year(date_range.wide_interval, years)
34
+ else
35
+ years[date_range.wide_interval.start[:year]] = Array.new(OSM_MONTHS.length) { |i| Array.new(MONTH_END_DAY[i]) { false } }
36
+ years = process_single_year(date_range.wide_interval, years)
37
+ end
38
+ else
39
+ for year in date_range.wide_interval.start[:year]..date_range.wide_interval.end[:year]
40
+ years[year] ||= Array.new(OSM_MONTHS.length) { |i| Array.new(MONTH_END_DAY[i]) { false } }
41
+ end
42
+ process_multiple_years(date_range.wide_interval, years)
43
+ end
44
+ else
45
+ unless get_iterator
46
+ years["always"] ||= Array.new(OSM_MONTHS.length) { |i| Array.new(MONTH_END_DAY[i]) { false } }
47
+ end
48
+ years = process_always(date_range.wide_interval, years, get_iterator)
49
+ end
50
+ years
51
+ end
52
+
53
+ def self.process_holidays(wide_interval, years)
54
+ if !wide_interval.end[:year].nil?
55
+ holidays = {}
56
+ for year in wide_interval.start[:year]..wide_interval.end[:year]
57
+ PublicHoliday.ph_for_year(year).each do |ht|
58
+ years[year][ht.month-1][ht.day-1] = true
59
+ end
60
+ end
61
+ else
62
+ PublicHoliday.ph_for_year(wide_interval.start[:year]).each do |ht|
63
+ years[wide_interval.start[:year]][ht.month-1][ht.day-1] = true
64
+ end
65
+ end
66
+ years
67
+ end
68
+
69
+ def self.process_always_holiday(wide_interval, years)
70
+ for year in (DateTime.now.year - 1)..(DateTime.now.year + 5)
71
+ years[year] ||= Array.new(OSM_MONTHS.length) { |i| Array.new(MONTH_END_DAY[i]) { false } }
72
+ PublicHoliday.ph_for_year(year).each do |ht|
73
+ years[year][ht.month-1][ht.day-1] = true
74
+ end
75
+ end
76
+ years
77
+ end
78
+
79
+ def self.remove_holiday!(date_range)
80
+ date_range.typical.intervals.each_with_index do |interval, interval_index|
81
+ date_range.remove_interval(interval_index) if interval.day_start == -2 && interval.day_end == -2
82
+ end
83
+ end
84
+
85
+ def self.build_day_array_from_dates(dates, get_iterator=false)
86
+ years = {}
87
+ dates.each do |date|
88
+ if !date.wide.start.nil? && !date.wide.start[:year].nil?
89
+ if date.wide.end.nil? || date.wide.end[:year].nil? || date.wide.start[:year] == date.wide.end[:year]
90
+ if !years[date.wide.start[:year]].nil?
91
+ years = process_single_year(date.wide, years)
92
+ else
93
+ years[date.wide.start[:year]] = Array.new(OSM_MONTHS.length) { |i| Array.new(MONTH_END_DAY[i]) { false } }
94
+ years = process_single_year(date.wide, years)
95
+ end
96
+ else
97
+ for year in date.wide.start[:year]..date.wide.end[:year]
98
+ years[year] ||= Array.new(OSM_MONTHS.length) { |i| Array.new(MONTH_END_DAY[i]) { false } }
99
+ end
100
+ process_multiple_years(date.wide, years)
101
+ end
102
+ else
103
+ unless get_iterator
104
+ years["always"] ||= Array.new(OSM_MONTHS.length) { |i| Array.new(MONTH_END_DAY[i]) { false } }
105
+ end
106
+ years = process_always(date.wide, years, get_iterator)
107
+ end
108
+ end
109
+ years
110
+ end
111
+
112
+ def self.process_always(wide_interval, years, get_iterator=false)
113
+ if !get_iterator
114
+ if wide_interval.start.nil?
115
+ years["always"] = Array.new(OSM_MONTHS.length) { |i| Array.new(MONTH_END_DAY[i]) { true } }
116
+ elsif !wide_interval.start[:day].nil?
117
+ if wide_interval.end.nil? || (wide_interval.end[:month].nil? && wide_interval.end[:day].nil?) ||
118
+ (wide_interval.start[:month] == wide_interval.end[:month] && wide_interval.start[:day] == wide_interval.end[:day])
119
+ years["always"][wide_interval.start[:month]-1][wide_interval.start[:day]-1] = true
120
+ elsif wide_interval.start[:month] == wide_interval.end[:month]
121
+ for day in wide_interval.start[:day]-1..wide_interval.end[:day]-1
122
+ years["always"][wide_interval.start[:month]-1][day] = true
123
+ end
124
+ elsif wide_interval.start[:month] != wide_interval.end[:month]
125
+ for month in wide_interval.start[:month]-1..wide_interval.end[:month]-1
126
+ if month == wide_interval.start[:month]-1
127
+ for day in wide_interval.start[:day]-1...MONTH_END_DAY[month]
128
+ years["always"][month][day] = true
129
+ end
130
+ elsif month == wide_interval.end[:month]-1
131
+ for day in 0..wide_interval.end[:day]-1
132
+ years["always"][month][day] = true
133
+ end
134
+ else
135
+ for day in 0...MONTH_END_DAY[month]
136
+ years["always"][month][day] = true
137
+ end
138
+ end
139
+ end
140
+ end
141
+ elsif !wide_interval.start[:month].nil?
142
+ if wide_interval.end.nil? || wide_interval.end[:month].nil? || wide_interval.start[:month] == wide_interval.end[:month]
143
+ years["always"][wide_interval.start[:month]-1].each_with_index do |month, i|
144
+ years["always"][wide_interval.start[:month]-1][i] = true
145
+ end
146
+ else
147
+ for month in wide_interval.start[:month]-1..wide_interval.end[:month]-1
148
+ years["always"][month].each_with_index do |day, i|
149
+ years["always"][month][i] = true
150
+ end
151
+ end
152
+ end
153
+ end
154
+ else
155
+ for year in (DateTime.now.year - 1)..(DateTime.now.year + 5)
156
+ if wide_interval.start.nil?
157
+ years[year] = Array.new(OSM_MONTHS.length) { |i| Array.new(MONTH_END_DAY[i]) { true } }
158
+ elsif !wide_interval.start[:day].nil?
159
+ years[year] ||= Array.new(OSM_MONTHS.length) { |i| Array.new(MONTH_END_DAY[i]) { false } }
160
+ if wide_interval.end.nil? || (wide_interval.end[:month].nil? && wide_interval.end[:day].nil?) ||
161
+ (wide_interval.start[:month] == wide_interval.end[:month] && wide_interval.start[:day] == wide_interval.end[:day])
162
+ years[year][wide_interval.start[:month]-1][wide_interval.start[:day]-1] = true
163
+ elsif wide_interval.start[:month] == wide_interval.end[:month]
164
+ for day in wide_interval.start[:day]-1..wide_interval.end[:day]-1
165
+ years[year][wide_interval.start[:month]-1][day] = true
166
+ end
167
+ elsif wide_interval.start[:month] != wide_interval.end[:month]
168
+ for month in wide_interval.start[:month]-1..wide_interval.end[:month]-1
169
+ if month == wide_interval.start[:month]-1
170
+ for day in wide_interval.start[:day]-1...MONTH_END_DAY[month]
171
+ years[year][month][day] = true
172
+ end
173
+ elsif month == wide_interval.end[:month]-1
174
+ for day in 0..wide_interval.end[:day]-1
175
+ years[year][month][day] = true
176
+ end
177
+ else
178
+ for day in 0...MONTH_END_DAY[month]
179
+ years[year][month][day] = true
180
+ end
181
+ end
182
+ end
183
+ end
184
+ elsif !wide_interval.start[:month].nil?
185
+ if wide_interval.end.nil? || wide_interval.end[:month].nil? || wide_interval.start[:month] == wide_interval.end[:month]
186
+ years[year][wide_interval.start[:month]-1].each_with_index do |month, i|
187
+ years[year][wide_interval.start[:month]-1][i] = true
188
+ end
189
+ else
190
+ for month in wide_interval.start[:month]-1..date.wide.end[:month]-1
191
+ years[year][month].each_with_index do |day, i|
192
+ years[year][month][i] = true
193
+ end
194
+ end
195
+ end
196
+ end
197
+ end
198
+ end
199
+ return years
200
+ end
201
+
202
+ def self.process_multiple_years(wide_interval, years)
203
+ if wide_interval.type == "year"
204
+ for year in wide_interval.start[:year]..wide_interval.end[:year]
205
+ years[year].each_with_index do |month,i|
206
+ month.each_with_index do |day,j|
207
+ years[year][i][j] = true
208
+ end
209
+ end
210
+ end
211
+ elsif wide_interval.type == "month"
212
+ for year in wide_interval.start[:year]..wide_interval.end[:year]
213
+ if year == wide_interval.start[:year]
214
+ for month in wide_interval.start[:month]-1..11
215
+ years[year][month].each_with_index do |day, i|
216
+ years[year][month][i] = true
217
+ end
218
+ end
219
+ elsif year == wide_interval.end[:year]
220
+ for month in 0..wide_interval.end[:month]-1
221
+ years[year][month].each_with_index do |day, i|
222
+ years[year][month][i] = true
223
+ end
224
+ end
225
+ else
226
+ for month in 0..11
227
+ years[year][month].each_with_index do |day, i|
228
+ years[year][month][i] = true
229
+ end
230
+ end
231
+ end
232
+ end
233
+ elsif wide_interval.type == "day"
234
+ for year in wide_interval.start[:year]..wide_interval.end[:year]
235
+ if year == wide_interval.start[:year]
236
+ for month in wide_interval.start[:month]-1..11
237
+ if month == wide_interval.start[:month]-1
238
+ for day in wide_interval.start[:day]-1...MONTH_END_DAY[month]
239
+ years[year][month][day] = true
240
+ end
241
+ else
242
+ for day in 0...MONTH_END_DAY[month]
243
+ years[year][month][day] = true
244
+ end
245
+ end
246
+ end
247
+ elsif year == wide_interval.end[:year]
248
+ for month in 0..wide_interval.end[:month]-1
249
+ if month == wide_interval.end[:month]-1
250
+ for day in 0..wide_interval.end[:day]-1
251
+ years[year][month][day] = true
252
+ end
253
+ else
254
+ for day in 0...MONTH_END_DAY[month]
255
+ years[year][month][day] = true
256
+ end
257
+ end
258
+ end
259
+ else
260
+ for month in 0..11
261
+ for day in 0...MONTH_END_DAY[month]
262
+ years[year][month][day] = true
263
+ end
264
+ end
265
+ end
266
+ end
267
+ end
268
+ return years
269
+ end
270
+
271
+ def self.process_single_year(wide_interval, years, always=false)
272
+ if wide_interval.type == "year"
273
+ years[wide_interval.start[:year]].each_with_index do |month,i|
274
+ month.each_with_index do |day,j|
275
+ years[wide_interval.start[:year]][i][j] = true
276
+ end
277
+ end
278
+ elsif wide_interval.type == "month"
279
+ if wide_interval.end.nil? || wide_interval.end[:month].nil? || wide_interval.start[:month] == wide_interval.end[:month]
280
+ years[wide_interval.start[:year]][wide_interval.start[:month]-1].each_with_index do |month, i|
281
+ years[wide_interval.start[:year]][wide_interval.start[:month]-1][i] = true
282
+ end
283
+ else
284
+ for month in wide_interval.start[:month]-1..wide_interval.end[:month]-1
285
+ years[wide_interval.start[:year]][month].each_with_index do |day, i|
286
+ years[wide_interval.start[:year]][month][i] = true
287
+ end
288
+ end
289
+ end
290
+ elsif wide_interval.type == "day"
291
+ if wide_interval.start[:month] == wide_interval.end[:month] || wide_interval.end[:month].nil?
292
+ if wide_interval.start[:day] == wide_interval.end[:day]
293
+ years[wide_interval.start[:year]][wide_interval.start[:month]-1][wide_interval.start[:day]-1] = true
294
+ else
295
+ for day in wide_interval.start[:day]-1..wide_interval.end[:day]-1
296
+ years[wide_interval.start[:year]][wide_interval.start[:month]-1][day] = true
297
+ end
298
+ end
299
+ else
300
+ for month in wide_interval.start[:month]-1..wide_interval.end[:month]-1
301
+ if month == wide_interval.start[:month]-1
302
+ for day in wide_interval.start[:day]-1...MONTH_END_DAY[month]
303
+ years[wide_interval.start[:year]][month][day] = true
304
+ end
305
+ elsif month == wide_interval.end[:month]-1
306
+ for day in 0..wide_interval.end[:day]-1
307
+ years[wide_interval.start[:year]][month][day] = true
308
+ end
309
+ else
310
+ for day in 0...MONTH_END_DAY[month]
311
+ years[wide_interval.start[:year]][month][day] = true
312
+ end
313
+ end
314
+ end
315
+ end
316
+ end
317
+ return years
318
+ end
319
+ end
320
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: opening_hours_converter
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.3.1
4
+ version: 1.3.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ziserman Martin
@@ -22,6 +22,7 @@ files:
22
22
  - lib/opening_hours_converter/date_range.rb
23
23
  - lib/opening_hours_converter/day.rb
24
24
  - lib/opening_hours_converter/interval.rb
25
+ - lib/opening_hours_converter/iterator.rb
25
26
  - lib/opening_hours_converter/opening_hours_builder.rb
26
27
  - lib/opening_hours_converter/opening_hours_date.rb
27
28
  - lib/opening_hours_converter/opening_hours_parser.rb
@@ -29,6 +30,7 @@ files:
29
30
  - lib/opening_hours_converter/opening_hours_time.rb
30
31
  - lib/opening_hours_converter/week.rb
31
32
  - lib/opening_hours_converter/wide_interval.rb
33
+ - lib/opening_hours_converter/year.rb
32
34
  homepage: https://github.com/Publidata/opening_hours_converter
33
35
  licenses:
34
36
  - AGPL-3.0