opening_hours_converter 1.9.0 → 1.9.1

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
  SHA256:
3
- metadata.gz: 0421f6038fb3bcaae15b1e29d5a4bb90b08d829e4bd68d2d4c3501307fa8b8c7
4
- data.tar.gz: '059ed79dab312bfa859028e9ec420ff99ae0e718a8723b98e61622fea8f85ae6'
3
+ metadata.gz: 78ca6634e9198554c0e918a2c3cbf684b0b8c2bb0dcf073433e13b0c1d3b71fc
4
+ data.tar.gz: 2f13efa6d51ac1734fd0cbd1742e3cd91be7e75fea61aab3dc83ca9db8614485
5
5
  SHA512:
6
- metadata.gz: 9319c1fc314fe58bbad62abf9e59c3525069f7324189dda6f938dad328869cd6a5b63ba65ab6965b3e3286e8bce782777d4be88bbac541a87daba0568071e0cb
7
- data.tar.gz: 26304defc99f58cceab36cf8bf0ae773651c2ab641b490601d1ff8b60446441af3c52234016e2a19ea73e1648ae05f014087eef9a8dcf5ce8ab1b16dcb5eea22
6
+ metadata.gz: f1f4c60f861ba37003d6acbe4e0db75591c82b67e454a8d8b276ed1fab6eb7e71342b0f494c9e8124540d396da9fc5646eefedb833b2843969b6bdd8b981d887
7
+ data.tar.gz: c1e034583c921b93fbea2bd9210329a7e49d8fc6f0a67ddc28a1bc3d1a8952b9e1058d2f404d5fac5dd90fbd5aa925669c0bcd029df2bb1627d243adcc38ab1d
@@ -0,0 +1,97 @@
1
+ require 'opening_hours_converter/constants'
2
+
3
+ module OpeningHoursConverter
4
+ class Token
5
+ include Constants
6
+
7
+ attr_accessor :type, :made_from
8
+ attr_reader :value, :start_index
9
+
10
+ def initialize(value, type, start_index, made_from = [])
11
+ @value = value
12
+ @type = type
13
+ @start_index = start_index
14
+ @made_from = made_from
15
+ end
16
+
17
+ def year?
18
+ integer? && @value.length == 4
19
+ end
20
+
21
+ def weekday?
22
+ string? && OSM_DAYS.any? { |day| day == @value }
23
+ end
24
+
25
+ def month?
26
+ string? && OSM_MONTHS.any? { |day| day == @value }
27
+ end
28
+
29
+ def week?
30
+ string? && @value == 'week'
31
+ end
32
+
33
+ def week_index?
34
+ # Nécessaire mais pas suffisant : 10 de 10:00 retourne true il faudra check le previous/next token pour décider ou garder le state week
35
+ integer? && @value.to_i <= 53 && @value.to_i >= 1
36
+ end
37
+
38
+ def weekday_modifier?
39
+ # Nécessaire mais pas suffisant : 10 de 10:00 retourne true il faudra check le previous/next token pour décider ou garder le state week
40
+ integer? && (@value.to_i <= 5 && @value.to_i >= 1) || @value.to_i == -1
41
+ end
42
+
43
+ def monthday?
44
+ # Nécessaire mais pas suffisant : 10 de 10:00 retourne true il faudra check le previous/next token pour décider
45
+ integer? && @value.to_i <= 31 && @value.to_i >= 1
46
+ end
47
+
48
+ def time?
49
+ # Nécessaire mais pas suffisant : 10 de Jan 10 retourne true il faudra check le previous/next token pour décider
50
+ integer? && @value.to_i < 60 && @value.to_i >= 0
51
+ end
52
+
53
+ def public_holiday?
54
+ string? && @value.downcase == 'ph'
55
+ end
56
+
57
+ def off?
58
+ string? && @value.downcase == 'off'
59
+ end
60
+
61
+ def string?
62
+ @type == :string
63
+ end
64
+
65
+ def integer?
66
+ @type == :integer
67
+ end
68
+
69
+ def hyphen?
70
+ @type == :hyphen
71
+ end
72
+
73
+ def comma?
74
+ @type == :comma
75
+ end
76
+
77
+ def quote?
78
+ @type == :quote
79
+ end
80
+
81
+ def colon?
82
+ @type == :colon
83
+ end
84
+
85
+ def slash?
86
+ @type == :slash
87
+ end
88
+
89
+ def opening_square_bracket?
90
+ @type == :opening_square_bracket
91
+ end
92
+
93
+ def closing_square_bracket?
94
+ @type == :closing_square_bracket
95
+ end
96
+ end
97
+ end
@@ -0,0 +1,228 @@
1
+ require 'opening_hours_converter/constants'
2
+
3
+ module OpeningHoursConverter
4
+ class Tokenizer
5
+ include Constants
6
+
7
+ attr_reader :tokens
8
+
9
+ def initialize(opening_hours_string)
10
+ @opening_hours_string = opening_hours_string
11
+ @index = 0
12
+ @tokens = []
13
+ tokenize
14
+ @tokens_handler = OpeningHoursConverter::TokensHandler.new(@tokens)
15
+ @tokens = @tokens_handler.tokens.map(&:value)
16
+ end
17
+
18
+ def tokenize
19
+ counter = 0
20
+ while @index < @opening_hours_string.length
21
+ raise 'ups' if counter > 200
22
+ skip_white_spaces
23
+ @tokens << handle_string if string?
24
+
25
+ skip_white_spaces
26
+ @tokens << handle_integer if integer?
27
+
28
+ skip_white_spaces
29
+ @tokens << handle_quote if quote?
30
+
31
+ skip_white_spaces
32
+ @tokens << handle_slash if slash?
33
+
34
+ skip_white_spaces
35
+ @tokens << handle_opening_square_bracket if opening_square_bracket?
36
+
37
+ skip_white_spaces
38
+ @tokens << handle_closing_square_bracket if closing_square_bracket?
39
+
40
+ skip_white_spaces
41
+ @tokens << handle_colon if colon?
42
+
43
+ skip_white_spaces
44
+ @tokens << handle_comma if comma?
45
+
46
+ skip_white_spaces
47
+ @tokens << handle_hyphen if hyphen?
48
+ counter += 1
49
+ end
50
+ end
51
+
52
+ private
53
+
54
+ def current_character
55
+ @opening_hours_string[@index]
56
+ end
57
+
58
+ def current_character?
59
+ !current_character.nil?
60
+ end
61
+
62
+ def handle_string
63
+ type = :string
64
+ start_index = @index
65
+ value = ''
66
+
67
+ while string? && current_character?
68
+ value << current_character
69
+ @index += 1
70
+ end
71
+
72
+ token(value, type, start_index)
73
+ end
74
+
75
+ def handle_integer
76
+ type = :integer
77
+ start_index = @index
78
+ value = ''
79
+
80
+ while integer? && current_character?
81
+ value << current_character
82
+ @index += 1
83
+ end
84
+
85
+ token(value, type, start_index)
86
+ end
87
+
88
+ def handle_quote
89
+ type = :quote
90
+ start_index = @index
91
+
92
+ value = current_character
93
+ @index += 1
94
+
95
+ while current_character?
96
+ if quote?
97
+ value << current_character
98
+ @index += 1
99
+ break
100
+ else
101
+ value << current_character
102
+ @index += 1
103
+ end
104
+ end
105
+
106
+ token(value, type, start_index)
107
+ end
108
+
109
+ def handle_slash
110
+ type = :slash
111
+ start_index = @index
112
+
113
+ value = current_character
114
+ @index += 1
115
+
116
+ token(value, type, start_index)
117
+ end
118
+
119
+ def handle_opening_square_bracket
120
+ type = :opening_square_bracket
121
+ start_index = @index
122
+
123
+ value = current_character
124
+ @index += 1
125
+
126
+ token(value, type, start_index)
127
+ end
128
+
129
+ def handle_closing_square_bracket
130
+ type = :closing_square_bracket
131
+ start_index = @index
132
+
133
+ value = current_character
134
+ @index += 1
135
+
136
+ token(value, type, start_index)
137
+ end
138
+
139
+ def handle_colon
140
+ type = :colon
141
+ start_index = @index
142
+
143
+ value = current_character
144
+ @index += 1
145
+
146
+ token(value, type, start_index)
147
+ end
148
+
149
+ def handle_comma
150
+ type = :comma
151
+ start_index = @index
152
+
153
+ value = current_character
154
+ @index += 1
155
+
156
+ token(value, type, start_index)
157
+ end
158
+
159
+ def handle_hyphen
160
+ type = :hyphen
161
+ start_index = @index
162
+
163
+ value = current_character
164
+ @index += 1
165
+
166
+ token(value, type, start_index)
167
+ end
168
+
169
+ def token(value, type, start_index)
170
+ OpeningHoursConverter::Token.new(value, type, start_index)
171
+ end
172
+
173
+ def skip_white_spaces
174
+ until current_character.nil? || !white_space?
175
+ @index += 1
176
+ end
177
+ end
178
+
179
+ def integer?
180
+ !(current_character =~ /[0-9]/).nil?
181
+ end
182
+
183
+ def white_space?
184
+ !(current_character =~ /\s/).nil?
185
+ end
186
+
187
+ def string?
188
+ # all char but space, digits and punctuations
189
+ !(current_character =~ /[^\s\d.,;:"()\[\]\-\_]/).nil?
190
+ end
191
+
192
+ def punctuation?
193
+ !(current_character =~ /[.,;:"'()\[\]]/).nil?
194
+ end
195
+
196
+ def quote?
197
+ current_character == '"'
198
+ end
199
+
200
+ def hyphen?
201
+ current_character == '-'
202
+ end
203
+
204
+ def colon?
205
+ current_character == ':'
206
+ end
207
+
208
+ def slash?
209
+ current_character == '/'
210
+ end
211
+
212
+ def semicolon?
213
+ current_character == ';'
214
+ end
215
+
216
+ def comma?
217
+ current_character == ','
218
+ end
219
+
220
+ def opening_square_bracket?
221
+ current_character == '['
222
+ end
223
+
224
+ def closing_square_bracket?
225
+ current_character == ']'
226
+ end
227
+ end
228
+ end
@@ -0,0 +1,466 @@
1
+ require 'opening_hours_converter/constants'
2
+
3
+ module OpeningHoursConverter
4
+ class TokensHandler
5
+ include Constants
6
+
7
+ attr_reader :tokens
8
+
9
+ def initialize(tokens)
10
+ @unhandled_tokens = tokens
11
+ @index = 0
12
+ @tokens = []
13
+
14
+ handle_tokens
15
+ end
16
+
17
+ def handle_tokens
18
+ while current_token?
19
+ if current_token.year?
20
+ @tokens << handle_year
21
+ next
22
+ end
23
+
24
+ if current_token.month?
25
+ @tokens << handle_month
26
+ next
27
+ end
28
+
29
+ if current_token.week?
30
+ @tokens << handle_week
31
+ next
32
+ end
33
+
34
+ if current_token.weekday?
35
+ @tokens << handle_weekday
36
+ next
37
+ end
38
+
39
+ if current_token_is_time?
40
+ @tokens << handle_time
41
+ next
42
+ end
43
+
44
+ if current_token.public_holiday?
45
+ @tokens << handle_public_holiday
46
+ next
47
+ end
48
+
49
+ if current_token_is_all_time?
50
+ @tokens << handle_all_time
51
+ next
52
+ end
53
+
54
+ if current_token.off?
55
+ @tokens << handle_off
56
+ next
57
+ end
58
+
59
+ if current_token.quote?
60
+ @tokens << handle_quote
61
+ next
62
+ end
63
+
64
+ if current_token.comma?
65
+ # catches "Mo off, Tu 10:00-20:00"
66
+ @index += 1
67
+ next
68
+ end
69
+
70
+ raise "can't read current token #{current_token}"
71
+ end
72
+ end
73
+
74
+ private
75
+
76
+ def add_current_token_value_to(value, leading = '', trailing = '')
77
+ "#{value}#{leading}#{current_token.value}#{trailing}"
78
+ end
79
+
80
+ def add_current_token_to(base_value, base_type, made_from, type = nil, leading = '', trailing = '')
81
+ base_type[type] = true unless type.nil? || type.length.zero?
82
+ value = add_current_token_value_to(base_value, leading, trailing)
83
+ made_from << current_token
84
+ @index += 1
85
+
86
+ [value, made_from, base_type]
87
+ end
88
+
89
+ def handle_year
90
+ type = { year: true }
91
+ start_index = current_token.start_index
92
+ value = current_token.value
93
+ made_from = [current_token]
94
+ @index += 1
95
+
96
+ while current_token?
97
+ if current_token.hyphen? || current_token.comma? || current_token.slash?
98
+ value, made_from, type = add_current_token_to(value, type, made_from)
99
+ next
100
+ end
101
+
102
+ if current_token.year?
103
+ type[:multi_year] = true
104
+ if previous_token.hyphen? || previous_token.comma?
105
+ value, made_from, type = add_current_token_to(value, type, made_from)
106
+ next
107
+ end
108
+ raise "you can\'t have two years with just space between them previous token: #{previous_token}, current token: #{current_token}"
109
+ end
110
+
111
+ if current_token.string?
112
+ break if current_token.weekday?
113
+
114
+ if current_token.week?
115
+ value, made_from, type = add_current_token_to(value, type, made_from, :week, ' ')
116
+ next
117
+ end
118
+
119
+ if current_token.month?
120
+ if previous_token.hyphen? || previous_token.comma?
121
+ value, made_from, type = add_current_token_to(value, type, made_from, :multi_month)
122
+ next
123
+ else
124
+ value, made_from, type = add_current_token_to(value, type, made_from, :month, ' ')
125
+ next
126
+ end
127
+ end
128
+ end
129
+
130
+ if current_token.integer?
131
+ break if current_token_is_time? # we don't want time range in the wide interval token
132
+ break if current_token_is_all_time? # nor 24/7
133
+
134
+ if type[:week]
135
+ if current_token.week_index?
136
+ if previous_token.slash?
137
+ value, made_from, type = add_current_token_to(value, type, made_from, :modified_week)
138
+ next
139
+ elsif previous_token.comma? || previous_token.hyphen?
140
+ value, made_from, type = add_current_token_to(value, type, made_from, :multi_week)
141
+ next
142
+ else
143
+ value, made_from, type = add_current_token_to(value, type, made_from, :week, ' ')
144
+ next
145
+ end
146
+ if current_token_is_week_modifier?
147
+ value, made_from, type = add_current_token_to(value, type, made_from, :modified_week)
148
+ next
149
+ end
150
+ end
151
+
152
+ elsif type[:month]
153
+ if current_token_monthday?
154
+ if previous_token.comma? || previous_token.hyphen?
155
+ value, made_from, type = add_current_token_to(value, type, made_from, :multi_month)
156
+ next
157
+ else
158
+ value, made_from, type = add_current_token_to(value, type, made_from, :month, ' ')
159
+ next
160
+ end
161
+ end
162
+ end
163
+ end
164
+
165
+ break
166
+ end
167
+
168
+ token(value, type, start_index, made_from)
169
+ end
170
+
171
+ def token(value, type, start_index, made_from)
172
+ OpeningHoursConverter::Token.new(value, type, start_index, made_from)
173
+ end
174
+
175
+ def handle_month
176
+ type = { month: true }
177
+ start_index = current_token.start_index
178
+ value = current_token.value
179
+ made_from = [current_token]
180
+ @index += 1
181
+
182
+ while current_token?
183
+ break if current_token_is_all_time?
184
+ break if current_token_is_time?
185
+
186
+ if current_token.hyphen? || current_token.comma? || current_token.slash?
187
+ value, made_from, type = add_current_token_to(value, type, made_from)
188
+ next
189
+ end
190
+
191
+ if current_token_monthday?
192
+ if previous_token.comma? || previous_token.hyphen?
193
+ value, made_from, type = add_current_token_to(value, type, made_from, :multi_monthday)
194
+ next
195
+ else
196
+ value, made_from, type = add_current_token_to(value, type, made_from, :monthday, ' ')
197
+ next
198
+ end
199
+ end
200
+
201
+ if current_token.month?
202
+ if previous_token.hyphen? || previous_token.comma?
203
+ value, made_from, type = add_current_token_to(value, type, made_from, :multi_month)
204
+ next
205
+ else
206
+ value, made_from, type = add_current_token_to(value, type, made_from, :month, ' ')
207
+ next
208
+ end
209
+ end
210
+
211
+ break
212
+ end
213
+
214
+ token(value, type, start_index, made_from)
215
+ end
216
+
217
+ def handle_week
218
+ type = { week: true }
219
+ start_index = current_token.start_index
220
+ value = current_token.value
221
+ made_from = [current_token]
222
+ @index += 1
223
+
224
+ while current_token?
225
+ break if current_token.string?
226
+ break if current_token_is_time?
227
+
228
+ if current_token.hyphen? || current_token.comma?
229
+ value, made_from, type = add_current_token_to(value, type, made_from, :multi_week)
230
+ next
231
+ end
232
+
233
+ if current_token.slash?
234
+ value, made_from, type = add_current_token_to(value, type, made_from, :modified_week)
235
+ next
236
+ end
237
+
238
+ if current_token.week_index?
239
+ if previous_token.week?
240
+ value = add_current_token_value_to(value, ' ')
241
+ else
242
+ value = add_current_token_value_to(value)
243
+ end
244
+ made_from << current_token
245
+ @index += 1
246
+ next
247
+ end
248
+
249
+ break
250
+ end
251
+
252
+ token(value, type, start_index, made_from)
253
+ end
254
+
255
+ def handle_weekday
256
+ type = { weekday: true }
257
+ start_index = current_token.start_index
258
+ value = current_token.value
259
+ made_from = [current_token]
260
+ @index += 1
261
+
262
+ while current_token?
263
+ break if current_token.integer?
264
+
265
+ if current_token.hyphen? || current_token.comma?
266
+ value, made_from, type = add_current_token_to(value, type, made_from, :multi_weekday)
267
+ next
268
+ end
269
+
270
+ if current_token.weekday?
271
+ value, made_from, type = add_current_token_to(value, type, made_from, :multi_weekday)
272
+ next
273
+ end
274
+
275
+ if current_token.public_holiday?
276
+ value, made_from, type = add_current_token_to(value, type, made_from, :public_holiday)
277
+ next
278
+ end
279
+
280
+ if current_token.opening_square_bracket?
281
+ value, made_from, type = add_current_token_to(value, type, made_from, :modified_weekday)
282
+
283
+ while current_token?
284
+ if current_token.closing_square_bracket?
285
+ value, made_from, type = add_current_token_to(value, type, made_from)
286
+ break
287
+ end
288
+
289
+ if current_token.hyphen? || current_token.weekday_modifier?
290
+ value, made_from, type = add_current_token_to(value, type, made_from)
291
+ next
292
+ end
293
+ end
294
+
295
+ next
296
+ end
297
+
298
+ break
299
+ end
300
+
301
+ token(value, type, start_index, made_from)
302
+ end
303
+
304
+ def handle_time
305
+ type = { time: true }
306
+ start_index = current_token.start_index
307
+
308
+ value = current_token.value
309
+ made_from = [current_token]
310
+ @index += 1
311
+
312
+ raise unless current_token.colon?
313
+ value, made_from, type = add_current_token_to(value, type, made_from)
314
+
315
+ raise unless current_token.time?
316
+ value, made_from, type = add_current_token_to(value, type, made_from)
317
+
318
+ raise unless current_token.hyphen?
319
+ value, made_from, type = add_current_token_to(value, type, made_from)
320
+
321
+ # second part of time range
322
+ raise unless current_token.time?
323
+ value, made_from, type = add_current_token_to(value, type, made_from)
324
+
325
+ raise unless current_token.colon?
326
+ value, made_from, type = add_current_token_to(value, type, made_from)
327
+
328
+ raise unless current_token.time?
329
+ value, made_from, type = add_current_token_to(value, type, made_from)
330
+
331
+ token(value, type, start_index, made_from)
332
+ end
333
+
334
+ def handle_public_holiday
335
+ type = { time: true }
336
+ start_index = current_token.start_index
337
+
338
+ value = current_token.value
339
+ made_from = [current_token]
340
+ @index += 1
341
+
342
+ if current_token.comma?
343
+ value, made_from, type = add_current_token_to(value, type, made_from)
344
+
345
+ weekdays_token = handle_weekday
346
+ value += weekdays_token.value
347
+ end
348
+
349
+ token(value, type, start_index, made_from)
350
+ end
351
+
352
+ def handle_all_time
353
+ type = { all_time: true }
354
+ start_index = current_token.start_index
355
+
356
+ value = current_token.value
357
+ made_from = [current_token]
358
+ @index += 1
359
+
360
+ raise unless current_token.slash?
361
+ value, made_from, type = add_current_token_to(value, type, made_from)
362
+
363
+ raise unless current_token.value == '7'
364
+ value, made_from, type = add_current_token_to(value, type, made_from)
365
+
366
+ token(value, type, start_index, made_from)
367
+ end
368
+
369
+ def handle_off
370
+ type = { off: true }
371
+ start_index = current_token.start_index
372
+
373
+ value = current_token.value
374
+ made_from = [current_token]
375
+ @index += 1
376
+
377
+ token(value, type, start_index, made_from)
378
+ end
379
+
380
+ def handle_quote
381
+ type = { comment: true }
382
+ start_index = current_token.start_index
383
+
384
+ value = current_token.value
385
+ made_from = [current_token]
386
+ @index += 1
387
+
388
+ token(value, type, start_index, made_from)
389
+ end
390
+
391
+ def current_token_is_time?
392
+ return false unless current_token?
393
+
394
+ if current_token.time?
395
+ if previous_token.hyphen?
396
+ return false unless next_token? && next_token.colon?
397
+ return true
398
+ end
399
+ if next_token? && next_token.hyphen?
400
+ return false unless previous_token.colon?
401
+ return true
402
+ end
403
+
404
+ return false unless previous_token.colon? || next_token? && next_token.colon?
405
+ return true
406
+ end
407
+
408
+ return false
409
+ end
410
+
411
+ def current_token_is_week_modifier?
412
+ current_token? &&
413
+
414
+ # check if current token is 2 in week 1-10/2
415
+ current_token.integer? && current_token.value.to_i <= 53 &&
416
+ previous_token? && previous_token.slash? &&
417
+ next_token?
418
+ end
419
+
420
+ def current_token_monthday?
421
+ current_token? &&
422
+
423
+ # check if current token is 22 in either Jan 22 off or Jan 21,22 or Jan 21-22
424
+ current_token.monthday? &&
425
+ previous_token? && previous_token.month? || previous_token.comma? || previous_token.hyphen? &&
426
+ next_token?
427
+ end
428
+
429
+ def current_token_is_all_time?
430
+ current_token? &&
431
+
432
+ # check if current token is 24 or / or 7 in 24/7
433
+ current_token.integer? &&
434
+ previous_token? && previous_token.slash? && current_token.value == '7' ||
435
+ next_token? && next_token.slash? && current_token.value == '24' ||
436
+
437
+ current_token.slash? &&
438
+ previous_token? && previous_token.value == '24' &&
439
+ next_token? && next_token.value == '7'
440
+ end
441
+
442
+ def current_token
443
+ @unhandled_tokens[@index]
444
+ end
445
+
446
+ def next_token
447
+ @unhandled_tokens[@index + 1]
448
+ end
449
+
450
+ def previous_token
451
+ @unhandled_tokens[@index - 1]
452
+ end
453
+
454
+ def current_token?
455
+ !current_token.nil?
456
+ end
457
+
458
+ def next_token?
459
+ !next_token.nil?
460
+ end
461
+
462
+ def previous_token?
463
+ !previous_token.nil?
464
+ end
465
+ end
466
+ end
@@ -0,0 +1,47 @@
1
+ module OpeningHoursConverter
2
+ module Utils
3
+ def reindex_sunday_week_to_monday_week(wday)
4
+ (wday + 6) % 7
5
+ end
6
+
7
+ def timstring_as_minutes(time)
8
+ values = time.split(':')
9
+ values[0].to_i * 60 + values[1].to_i
10
+ end
11
+
12
+ def add_days_to_time(time, days)
13
+ time + days * seconds_in_day
14
+ end
15
+
16
+ def day_difference(from, to)
17
+ to - from
18
+ end
19
+
20
+ def week_difference(from, to)
21
+ day_diff = to - from
22
+ day_diff -= (day_diff % 7)
23
+ (day_diff / 7).to_i
24
+ end
25
+
26
+ def seconds_in_day
27
+ 24 * 60 * 60
28
+ end
29
+
30
+ def leap_year?(year = Time.now.year)
31
+ year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)
32
+ end
33
+
34
+ def last_day_of_month(month, year)
35
+ return [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][month] unless leap_year?(year) && month == 1
36
+ return 29
37
+ end
38
+
39
+ def time_to_datetime(time)
40
+ DateTime.new(time.year, time.month, time.day, time.hour, time.min, time.sec, Rational(time.gmt_offset / 3600, 24))
41
+ end
42
+
43
+ def datetime_to_time(datetime)
44
+ Time.new(datetime.year, datetime.month, datetime.day, datetime.hour, datetime.min, datetime.sec, datetime.zone)
45
+ end
46
+ end
47
+ 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.9.0
4
+ version: 1.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ziserman Martin
@@ -57,6 +57,10 @@ files:
57
57
  - lib/opening_hours_converter/opening_hours_rule.rb
58
58
  - lib/opening_hours_converter/opening_hours_time.rb
59
59
  - lib/opening_hours_converter/public_holiday.rb
60
+ - lib/opening_hours_converter/token.rb
61
+ - lib/opening_hours_converter/tokenizer.rb
62
+ - lib/opening_hours_converter/tokens_handler.rb
63
+ - lib/opening_hours_converter/utils.rb
60
64
  - lib/opening_hours_converter/week.rb
61
65
  - lib/opening_hours_converter/wide_interval.rb
62
66
  - lib/opening_hours_converter/year.rb