Определите, находится ли Текущее время в пределах временных диапазонов. Если не найдено, каково следующее открытое окно - PullRequest
0 голосов
/ 12 ноября 2018

У меня есть приложение, в котором мне нужно отправлять сообщения предприятиям, только если они находятся в пределах установленных окон сообщений.

у бизнеса может быть набор окон с понедельника по пятницу с 10:00 до 15:00, с 18:00 до 23:00 по субботам.- с 2:00 до 6:00, с 15:00 до 16:00

Это пример

Таким образом, у бизнеса может быть несколько рабочих окон в день, и они могут различаться в зависимости от дня недели.Каждый бизнес также будет находиться в отдельном часовом поясе, поэтому это также необходимо учитывать.

Когда приходит сообщение для доставки, мне нужно знать, находится ли текущее время в пределах окна.Если это не так, он будет поставлен в очередь, и мне нужно доставить его в следующее открытое окно.

Я немного растерялся, где и как начать с этого.Любая помощь будет оценена.Извините, если вопрос не был достаточно детальным.

Спасибо.

1 Ответ

0 голосов
/ 12 ноября 2018

Предположим, вам нужно было создать хеш, ключи которого являются предприятиями, а значения - окнами, окна - это массив из семи массивов, по одному на каждый день недели:

windows = [sun_windows, mon_windows, ... , sat_windows]

Каждое ежедневное окномассив диапазонов вида first_sec..last_sec, first_sec и last_sec, представляющих секунды с полуночи.Эти диапазоны упорядочены в том смысле, что конец каждого диапазона (в секундах) меньше начала следующего диапазона.

Предположим, например, что для определенного бизнеса в понедельник было два окна, 8:00-12:00и 13:00-17:00.Тогда

mon_windows = [8*3600..12*3600, 13*3600..17*3600]
  #=> [28800..43200, 46800..61200]

Предположим, теперь кто-то хотел знать, были ли в данный момент [:mon, 44000] в пределах окна для этого бизнеса.Для этой задачи мы могли бы использовать следующий метод:

def covered?(windows_today, secs)
  windows_today.each do |r|
    return [false, r] if r.begin > secs
    return true if r.cover?(secs)
  end
  false
end

Поскольку понедельник - второй день недели (смещение 1), мы должны выполнить:

covered?(windows[1], 44000)
  #=> [false, 46800..61200]

где:

windows_today = windows[1]
  #=> [28800..43200, 46800..61200]

Существует три возможных возвращаемых значения этого метода.

  • true: сообщение может быть доставлено немедленно;
  • [false, r]: сообщение не можетбыть доставленным немедленно, но может быть доставлено в течение (следующего) окна (диапазона) r в тот же день;и
  • false: сообщение не может быть доставлено в тот же день.

В зависимости от требований, возможно, потребуется только r.begin (46800 в примере) ввторой случай.

В этом примере 44000 находится за пределами окна понедельника, а следующее окно - это диапазон 46800..61200 того же дня.

Мы бы закончили, если бы false не было возвращено.В этом случае нам нужно определить следующее окно.

def next_window(windows, start_day)
  dow = 7.times.find { |i| windows[(start_day + i) % 7].any? }
  dow = (start_day + dow) % 7 
  [dow, windows[dow].first]
end

, где start_day равно 1 плюс номер текущего дня недели (например, 1 для понедельника, что составляет * 1053).*).

Обратите внимание: если бизнес открыт только в понедельник windows[start_day+i) % 7] #=> [] для i = 0..5 (т. Е. windows[start_day+i) % 7].first #=> nil), а метод вернет

next_window(windows, 2)
  #[1, 28800..43200]

28800..43200Будучи первым окном следующего понедельника.

Что касается часовых поясов, казалось бы, что самое простое - сделать Гренвич по среднему времени.

...