这里必须有一些简单的东西被忽视......
我一直在尝试各种方法来创建基本的IceCube
计划(https://github.com/seejohnrun/ice_cube)。总体目标是使用IceCube
在“房间预订”rails应用程序中允许“价格计划”。
第一种方案是创建一个基本的schedule
,其中包含特定的start_time
和end_time
- 仅发生一次。 IceCube
可以做到这一点,对吗?
时间表将从start_time
开始,到end_time
结束。我希望能够检查日期或时间occurs_on?
此时间表,以确定是否应调整房价。
所以在控制台中我尝试创建一个基本的时间表,并且由于5.days
为start_time
且Time.now
为end_time
,因此从现在开始Time.now + 30.days
{1}}。但它似乎永远不会真实......
1.8.7 :001 > schedule = IceCube::Schedule.new(Time.now, :end_time => Time.now + 30.days)
=> #<IceCube::Schedule:0xb619d604 @all_recurrence_rules=[], @duration=nil, @end_time=Tue Jan 08 09:13:11 -0600 2013, @all_exception_rules=[], @start_time=Sun Dec 09 09:13:11 -0600 2012>
1.8.7 :002 > schedule.occurs_on? Date.today + 5.days
=> false
1.8.7 :005 > schedule.occurs_at? Time.now + 5.days
=> false
1.8.7 :006 > schedule.occurring_at? Time.now + 5.days
=> false
添加重复规则
1.8.7 :018 > schedule.rrule IceCube::Rule.monthly
=> [#<IceCube::MonthlyRule:0xb687a88c @validations={:base_day=>[#<IceCube::Validations::ScheduleLock::Validation:0xb6875b0c @type=:day>], :base_hour=>[#<IceCube::Validations::ScheduleLock::Validation:0xb6875abc @type=:hour>], :interval=>[#<IceCube::Validations::MonthlyInterval::Validation:0xb6875d28 @interval=1>], :base_min=>[#<IceCube::Validations::ScheduleLock::Validation:0xb6875a6c @type=:min>], :base_sec=>[#<IceCube::Validations::ScheduleLock::Validation:0xb6875a1c @type=:sec>]}, @interval=1>]
然后检查Date.today
是否有效......
1.8.7 :025 > schedule.occurs_on? Date.today
=> true
但是检查发生了什么? for Date.today + 10.days
仍然返回false ...为什么?
1.8.7 :026 > schedule.occurs_on? Date.today + 10.days
=> false
那我在忽视/做错了什么?或者设置IceCube::Schedule start_time
和end_time
有什么意义 - 它们似乎没有效果......?
IceCube
对于具有开始和结束时间的单个事件事件不起作用吗?
另一个示例场景,房间所有者希望在假日季节提高房价。因此,房间所有者创建了一个价格表,从2012年12月1日开始到2013年1月7日结束。(不应该 重复,但如果所有者想要的话,可以。)
然后,当人们搜索房间时,如果请求的住宿occurs_on?
是假日价格表,则会调整价格
我是否需要将start_time
和end_time
存储在时间表之外并手动检查?
或者是否有更适合的宝石/工具来协助这种日程管理?
答案 0 :(得分:7)
你误解了时间表和规则是如何运作的。
首先,了解start_time
非常重要。计划的每次出现都基于此,并且计划返回与开始时间的特定间隔匹配的时间。间隔由规则确定。
您的示例不起作用,因为“从现在开始的5天”不是计划开始时间的每月间隔。从开始时间开始的28,30或31天将匹配,具体取决于月份。
start = Time.utc(2013, 05, 17, 12, 30, 00) # 2013-05-17 12:30:00 UTC
schedule = IceCube::Schedule.new(start)
schedule.add_recurrence_rule IceCube::Rule.monthly
schedule.occurs_on? start + 5.days #=> false
schedule.occurs_on? start + 31.days #=> true
其次,end_time
与start_time
一起设置每个出现的持续时间。因此,如果您的开始时间是09:00,结束时间是17:00,则每次出现的持续时间为8小时。
这创建了occurs_at?(t1)
和occurring_at?(t1)
之间的区别:第一个仅在给定时间与出现的开始完全匹配时才为真;第二个在持续时间的任何时间都是真的。 occurs_on?(d1)
匹配给定日期中的任何时间。
arrival = Time.utc(2013, 5, 1, 9, 0, 0)
departure = Time.utc(2013, 5, 1, 17, 0, 0)
schedule = IceCube::Schedule.new(arrival, end_time: departure)
schedule.add_recurrence_rule IceCube::Rule.weekly.day(1, 2, 3, 4, 5) # M-F
schedule.occurs_at? arrival #=> true
schedule.occurs_at? arrival + 1.second #=> false
schedule.occurring_at? arrival + 1.second #=> true
schedule.occurring_at? departure + 1.second #=> false
对于你正在做的事情,你可以尝试以下两种方法之一:
这取决于您需要如何根据计划显示或验证时间。以下是两者的示例:
arrival = Time.utc(2013, 5, 1)
departure = Time.utc(2013, 5, 31)
# single occurrence
schedule = IceCube::Schedule.new(arrival, duration: 31.days)
# daily occurrence
schedule = IceCube::Schedule.new(arrival, duration: 1.day)
schedule.add_recurrence_rule IceCube::Rule.daily.until(departure)
答案 1 :(得分:1)
经过一些更多的测试后,我认为使用IceCube的SingleOccurrenceRule是发生一次事件的正确方法。
要制定仅在计划start_time
和end_time
之间的日期发生的计划,我可以执行以下操作。
使用start和end_time创建IceCube::Schedule
:
1.8.7 :097 > schedule = IceCube::Schedule.new(Time.now, :end_time => Time.now + 30.days)
=> #<IceCube::Schedule:0xb63caabc @all_recurrence_rules=[], @duration=nil, @end_time=Wed Jan 09 00:03:36 -0600 2013, @all_exception_rules=[], @start_time=Mon Dec 10 00:03:36 -0600 2012>
将计划中发生的所有日期放入数组中。
1.8.7 :098 > days_in_schedule = []
=> []
1.8.7 :099 > schedule.start_time.to_date.upto(schedule.end_time.to_date) { |d| puts d; days_in_schedule << d }
迭代数组并为计划中的每一天创建SingleOccurrenceRule。然后测试几个日期。在30天内,发生在?是真的,在30天之外,发生了吗?是假的。这似乎是正确的,但在检查schedule.occurs_on? Date.today
时它仍然返回false。的为什么?!?!吗
1.8.7 :100 > days_in_schedule.each { |d| schedule.rtime Time.parse(d.to_s) }
1.8.7 :109 > schedule.terminating?
=> true
1.8.7 :110 > schedule.occurs_on? Date.today + 5.days
=> true
1.8.7 :111 > schedule.occurs_on? Date.today + 55.days
=> false
1.8.7 :135 > schedule.occurs_on? Date.today
=> false