Подход
Любопытно, что вопрос сформулирован в терминах DateTime
объектов, учитывая, что основная проблема, по-видимому, заключается просто в определении того, упадет ли запланированное время спортивного матча. в течение определенного времени. Использование DateTime
объектов является лишь одним из способов решения проблемы, но не единственным. В этом смысле вопрос может попасть под заголовок XY problem .
Фактически, я считаю, что использование DateTime
объектов усложняет проблему излишне. * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *. Каждый раз проще express как просто двухэлементный массив, который содержит часы и минуты. Например, временное окно, которое расширяется с 12:30 (24-часовые часы) до 22:00 этого вечера, может быть выражено как диапазон: 1
window = [12, 30]..[22, 0]
Время события можно определить аналогично: 2
event_time = [15, 45]..[19, 30]
Для удобства я буду ссылаться на двухэлементные массивы, которые являются конечными точками этих диапазонов, просто на "времена".
Важным соображением является то, что время начала и окончания спортивного мероприятия не обязательно должно совпадать с одним днем. Примером может служить турнир, в котором матчи должны проходить в промежутке между 12:30 (24-часовой формат) и 1:00 (AM) следующего дня. Это не необычно. Это временное окно будет выражаться:
window = [12, 30]..[1, 0]
Я предполагаю:
- время окончания меньше, чем через 24 часа после соответствующего времени начала; и
- временной интервал одинаков каждый день.
Конечно, можно внести изменения в приведенный ниже код, если одно из предположений не выполняется.
Код
Построим метод valid?
, который возвращает true
(иначе false
), если данное событие попадает в заданное временное окно:
def valid?(event_time, window)
e = time_to_mins(event_time.begin)..time_to_mins(event_time.end)
w = time_to_mins(window.begin)..time_to_mins(window.end)
if w.begin <= w.end
w.cover?(e)
else
(w.begin <= e.begin || e.begin <= w.end) &&
(w.begin <= e.end || e.end <= w.end)
end
end
def time_to_mins(time_arr)
60 * time_arr.first + time_arr.last
end
Примеры
time_to_mins [ 0, 10] #=> 10
time_to_mins [22, 30] #=> 1350
window = [ 9, 30]..[22, 30]
valid?([13, 45]..[16, 30], window) #=> true
valid?([ 8, 45]..[11, 30], window) #=> false
valid?([22, 15]..[ 0, 15], window) #=> false
window = [12, 30]..[1, 0]
valid?([16, 15]..[19, 30], window) #=> true
valid?([22, 45]..[ 0, 30], window) #=> true
valid?([ 0, 15]..[ 0, 45], window) #=> true
valid?([22, 45]..[ 1, 30], window) #=> false
valid?([ 0, 15]..[ 1, 45], window) #=> false
1. При желании, в качестве альтернативы, можно express раз использовать хэши, например, { hour: 12, min: 30, sec: 0 }
.
2. Информация для каждого события может храниться в более крупной структуре данных, такой как event = { start_date: [2020, 2, 7], time_block: [[22, 45, 0]..[ 0, 30, 0]], player_1: 'R. Federer', player_2: 'R. Nadal' }
, с использованием только event[:time_block]
в приведенном выше расчете.