opening_hours_converter 1.3.1 → 1.3.2

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 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