ice-cube-ruby / ice_cube

Ruby Date Recurrence Library - Allows easy creation of recurrence rules and fast querying
MIT License
2.41k stars 358 forks source link

Single Occurrence With Multiple Times For a Day #101

Closed swalke16 closed 12 years ago

swalke16 commented 12 years ago

I found this question on StackOverflow that shows how you can have multiple occurrences of a schedule on a single day using the hour_of_day and minute_of_hour methods on a rule.

This works great for weekly, and daily recurrences, but I couldn't seem to find a way to make a non repeating schedule that occurs multiple times in a day. For example I want a schedule that looks like:

5 am 6 am 5pm On October 15th

I tried using daily and hourly rules with a 0 interval but this just throws a division by zero error on getting occurrences.

seejohnrun commented 12 years ago

Something like this should be what you want:

schedule = IceCube::Schedule.new Time.now
schedule.rrule IceCube::Rule.yearly.day_of_month(15).month_of_year(:october).hour_of_day(5, 6, 17).minute_of_hour(0).second_of_minute(0)
schedule.first(10) # [2012-10-15 05:00:00 -0400, 2012-10-15 06:00:00 -0400, 2012-10-15 17:00:00 -0400, 2013-10-15 05:00:00 -0400, 2013-10-15 06:00:00 -0400, 2013-10-15 17:00:00 -0400, 2014-10-15 05:00:00 -0400, 2014-10-15 06:00:00 -0400, 2014-10-15 17:00:00 -0400, 2015-10-15 05:00:00 -0400]
swalke16 commented 12 years ago

The problem with that solution is that it repeats yearly. I want this event to occur on one day only, but three times on that one day.

My latest attempt was this:

schedule = IceCube::Schedule.new Time.now
rule = IceCube::Rule.daily 1
rule.hour_of_day(5).minute_of_hour(0)
rule.hour_of_day(6).minute_of_hour(0)
rule.hour_of_day(17).minute_of_hour(0)
rule.until(Time.now + 1.day)
schedule.add_recurrence_rule rule

sc.remaining_occurrences
=> []

sc.all_occurrences # goes into infinite loop
seejohnrun commented 12 years ago

Then you would want something like:

the_year = 2012
schedule = IceCube::Schedule.new Time.new(the_year, 1, 1)
schedule.rrule IceCube::Rule.yearly.day_of_month(15).month_of_year(:october).hour_of_day(5, 6, 17).minute_of_hour(0).second_of_minute(0).
  until(Time.new(the_year + 1, 1, 1) - 1) # ensure no dates in 2013
schedule.all_occurrences # [2012-10-15 05:00:00 -0400, 2012-10-15 06:00:00 -0400, 2012-10-15 17:00:00 -0400]
martinstreicher commented 7 years ago

I used this solution today, albeit with .count(1) rather than until.