Ruby Date Recurrence Library
ice_cube
# install
$ gem install
# get the code
$ gem clone git://github.com/seejohnrun/ice_cube
# The fridays in October that are on the 13th of the month
Rule.weekly.day(:friday).day_of_month(13).month_of_year(:october)
ice_cube
offers a hash-backed to_yaml implementation, making it super easy (and safe) to serialize schedule objects to your data store:
# YAML
yaml = schedule.to_yaml
schedule = Schedule.from_yaml(yaml)
# Hash
hash = schedule.to_hash
schedule = Schedule.from_hash(hash)
# A complex rule
rule = Rule.daily.day_of_week(:monday => [1, -1]).month_of_year(:april)
rule.to_s # Daily in April on the last and 1st Mondays
rule.to_ical # FREQ=DAILY;BYMONTH=4;BYDAY=-1MO,1MO
rule.to_yaml # :rrules: \n- :until: \n :count: ...
Multiple validations on the same rule, result in an AND (&&) relationship
# On Wednesdays THAT ARE ALSO in April
schedule.add_recurrence_rule Rule.weekly.day(:wednesday).month_of_year(:april)
Multiple rules in the same schedule, result in an OR (||) relationship
# On Thursdays and the 100th day of the year
schedule.add_recurrence_rule Rule.weekly.day(:thursday)
schedule.add_recurrence_rule Rule.day_of_year(100)
# Create a schedule for every day in May
schedule = Schedule.new(Time.now)
schedule.add_recurrence_rule Rule.daily.month_of_year(:may)
# Does it occur at a certain time?
schedule.occurs_at?(Time.local(2010, 11, 1)) # false
# Does it occur on a certain date?
schedule.occurs_on?(Date.today)
# All of the occurrences between two Times
schedule.occurrences_between(Time.local(2010, 1, 1), Time.local(2010, 12, 1))
# When are the first 10 occurrences
schedule.first(10) # [Thu May 13 18:01:46 -0400 2010, Fri May 13 ...]
# All of the occurrences between now and another Time
schedule.occurrences(Time.local(2010, 12, 1)) # [Thu May 13 18:01:46 -0400 2010]
# If your schedule has a duration, occurring_at? is important
ten = Time.new(2010, 5, 6, 10, 0, 0)
schedule = Schedule.new(ten, :duration => 3600)
schedule.add_recurrence_rule Rule.daily
schedule.occurring_at?(Time.local(2010, 5, 6, 10, 30, 0)) # true
# If your schedule needs a hard-set end time, that's easy too
schedule = Schedule.new(Time.now, :end_time => Time.now + 3600)
schedule.occurs_at?(Time.now + 3601) # false