Однократное событие с драгоценным камнем ice_cube с использованием start_time и end_time

Здесь должно быть упущено что-то простое...

Я пробовал различные способы создания базового расписания 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.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 не работает для однократных событий с временем начала и окончания?

Другой пример сценария: владелец комнаты хочет поднять цены на комнату в праздничный сезон. Таким образом, владелец комнаты создает прейскурант, который начинается 1 декабря 2012 г. и заканчивается 7 января 2013 года (не должно должно повторяться, но может, если владелец захочет).

Затем, когда люди ищут номера, цены будут скорректированы, если запрошенное пребывание occurs_on? соответствует графику отпускных цен.

Мне нужно хранить start_time и end_time вне расписания и проверять вручную или что-то в этом роде?

Или есть более подходящий драгоценный камень/инструмент для помощи в таком управлении расписанием?


person b2tech    schedule 09.12.2012    source источник
comment
Мы используем github.com/bokmann/fullcalendar-rails для повторяющихся событий.   -  person Michael Durrant    schedule 09.12.2012
comment
Спасибо за предложение. fullcalendar-rails выглядит как хорошая настройка календаря. Думаю, теперь я буду искать другие более простые решения. Либо я неправильно использую IceCube, либо что-то с ним просто странно (например, мой ответ ниже проверяет, что occurs_on? Date.today возвращает false, когда событие явно происходит_on? Date.today...)   -  person b2tech    schedule 11.12.2012
comment
@b2tech Столкнулся с похожей проблемой и зарегистрировал ее на github.com/seejohnrun/ice_cube/issues/165. .Ждем комментариев от сопровождающих Gem.   -  person Jignesh Gohel    schedule 27.04.2013


Ответы (2)


Вы неправильно понимаете, как работают расписания и правила.

Во-первых, важно понять 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

Для того, что вы делаете, вы можете попробовать один из двух подходов:

  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)
person Andrew Vit    schedule 17.05.2013
comment
Спасибо, Эндрю, это помогло мне понять несколько более мелких деталей. - person Kenneth Kalmer; 17.03.2014

После еще нескольких тестов я думаю, что использование SingleOccurrenceRule IceCube — это правильный способ получить однократное событие.

Чтобы иметь расписание, которое происходит только в дни между расписанием start_time и end_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 дней происходит_на? верно, вне 30 дней, происходит_на? является ложным. Это кажется правильным, за исключением того, что он по-прежнему возвращает 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 
person b2tech    schedule 10.12.2012