Class: OpeningHoursConverter::OpenIntervals

Inherits:
Object
  • Object
show all
Includes:
Constants, Utils
Defined in:
lib/opening_hours_converter/open_intervals.rb

Overview

Projects parsed date ranges onto a concrete window and returns the open intervals it contains.

Rules are applied in the order they were parsed, and a later rule overrides an earlier one on the minutes it selects, as the OpenStreetMap specification requires: "Jul-Aug off; Mo-Fr 09:00-17:00" is open in July, while "Mo-Fr 09:00-17:00; Jul-Aug off" is closed.

A rule behind a "||" is the exception. It is a fallback: it speaks only for the minutes the rules before it leave closed, and never over the ones they open. "Mo-Fr 08:00-12:00 || Sa 10:00-12:00" opens on Saturday and changes nothing from Monday to Friday.

Constant Summary collapse

OPEN_ENDED =

The state of a minute an open-ended time covers, told apart from a plain open minute so that the two never run into a single interval.

:open_ended

Constants included from Constants

Constants::DAYS, Constants::DAYS_MAX, Constants::EASTER_WEEKDAY, Constants::IRL_DAYS, Constants::IRL_MONTHS, Constants::MINUTES_MAX, Constants::MONTH_END_DAY, Constants::OSM_DAYS, Constants::OSM_DAYS_ABBREVIATIONS, Constants::OSM_MONTHS, Constants::PH_WEEKDAY, Constants::YEAR_DAYS_MAX

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Utils

#add_days_to_time, #datetime_to_time, #day_difference, #last_day_of_month, #leap_year?, #reindex_sunday_week_to_monday_week, #seconds_in_day, #time_to_datetime, #timstring_as_minutes, #week_difference

Constructor Details

#initialize(from, to) ⇒ OpenIntervals

Returns a new instance of OpenIntervals.



29
30
31
32
33
34
35
36
37
38
39
# File 'lib/opening_hours_converter/open_intervals.rb', line 29

def initialize(from, to)
  @from = from
  @to = to
  # One day before the window, so an interval crossing midnight into it is
  # not lost.
  @first_date = from.to_date - 1
  @last_date = to.to_date
  @masks = {}
  @fallback = false
  @holidays = {}
end

Class Method Details

.call(opening_hours_string, from, to) ⇒ Object



24
25
26
27
# File 'lib/opening_hours_converter/open_intervals.rb', line 24

def self.call(opening_hours_string, from, to)
  date_ranges = OpeningHoursConverter::OpeningHoursParser.new.parse(opening_hours_string)
  new(from, to).apply(date_ranges).intervals
end

Instance Method Details

#apply(date_ranges) ⇒ Object



41
42
43
44
45
46
47
48
49
50
51
# File 'lib/opening_hours_converter/open_intervals.rb', line 41

def apply(date_ranges)
  expand(date_ranges).each { |date_range, bounds| apply_date_range(date_range, bounds) }

  fallback = date_ranges.first&.fallback_ranges
  return self if fallback.nil? || fallback.empty?

  # Everything past a "||" is a fallback, and stays one: a chained
  # "a || b || c" nests, c falling back on what a and b leave closed.
  @fallback = true
  apply(fallback)
end

#intervalsObject



53
54
55
56
# File 'lib/opening_hours_converter/open_intervals.rb', line 53

def intervals
  runs.select { |run| run[:end] > @from && run[:start] < @to }
      .map { |run| { start: [run[:start], @from].max, end: [run[:end], @to].min } }
end