我有一个应用程序,仅当它们在设置的消息窗口内时,才需要向他们发送消息。
一家企业可能在周一至周五上午10点至下午3点,下午6点至晚上11点有一组Windows 星期日2 am-6am,3 pm-4pm
这是一个样本
因此,一家公司每天可能有多个业务窗口,并且它们可能在一周中的每一天有所不同。每个业务还将处于不同的时区,因此也必须加以考虑。
当有邮件要发送时,我需要知道当前时间是否在窗口内。如果不是,它将排队,我需要在下一个打开的窗口中交付它。
我有点无所适从,从何处开始。任何帮助,将不胜感激。很抱歉,这个问题不够详细。
谢谢。
答案 0 :(得分:0)
假设您要构造一个散列,其键是业务,其值是窗口,该窗口是由七个数组组成的数组,一个星期中的每一天:
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
,等于start_day = 2
)。
请注意,如果仅在windows[start_day+i) % 7] #=> []
(i = 0..5
)的windows[start_day+i) % 7].first #=> nil
星期一营业,则该方法将返回
next_window(windows, 2)
#[1, 28800..43200]
28800..43200
是下周一的第一个窗口。
关于时区,使所有时间成为格林威治标准时间似乎最简单。