4

这里一定有一些简单的东西被忽略了......

我一直在尝试各种方法来创建基本IceCube时间表(https://github.com/seejohnrun/ice_cube)。总体目标是IceCube在“房间预订”rails 应用程序中使用“价格表”。

第一种情况是创建一个schedule具有特定start_timeend_time仅发生一次的基础。IceCube可以这样做,对吗?

时间表将从 开始并在start_time结束end_time。我希望能够检查occurs_on?此时间表的日期或时间,以确定是否应调整房价。

因此,在控制台中,我尝试创建一个基本时间表,并希望它5.days从现在开始发生,因为start_timeisTime.nowend_timeis Time.now + 30.days。但它似乎永远不会返回真实......

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 

但检查发生_on?forDate.today + 10.days仍然返回 false ......为什么?

1.8.7 :026 > schedule.occurs_on? Date.today + 10.days
 => false 

那么我忽略了什么/做错了什么?或者设置一个IceCube::Schedule start_timeend_time- 它们似乎没有效果......有什么意义?

IceCube不适用于具有开始和结束时间的单次事件?

另一个示例场景是,房主希望提高假日季节的房价。因此,房主创建了一个从 2012 年 12 月 1 日开始到 2013 年 1 月 7 日结束的价格表。(不必重复,但如果业主愿意,可以重复)。

然后当人们在搜索房间时,如果请求的住宿occurs_on?是假期价格表,价格将被调整

我是否需要在日程表之外存储start_timeend_time手动检查或其他什么?

或者是否有更适合的 gem / 工具来协助这种日程管理?

4

2 回答 2

8

您误解了时间表和规则的工作方式。

首先,重要的是要了解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_timestart_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

对于您正在做的事情,您可以尝试以下两种方法之一:

  1. 长达一个月的事件
  2. 一个月后结束的日常事件

这取决于您需要如何根据计划显示或验证时间。这是两者的示例:

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)
于 2013-05-17T07:57:57.613 回答
1

经过更多测试后,我认为使用 IceCube 的 SingleOccurrenceRule 是单次发生事件的正确方法。

要有一个只发生在日程表和我之间的日子的日程表start_timeend_time我可以做如下的事情。

创建一个IceCube::Schedule带有 start 和 end_time 的:

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 天内,发生_on? 是真的,在 30 天之外,发生?是假的。这似乎是正确的,除了在检查 if 时它仍然返回 false schedule.occurs_on? Date.today为什么?!?!?

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 
于 2012-12-10T06:18:20.320 回答