### Schedule to_s Example Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Create a human-readable summary of a schedule, including its start time, recurrence rules, and any exceptions. ```ruby start = Time.local(2024, 1, 1, 9, 0, 0) schedule = IceCube::Schedule.new(start) do |s| s.add_recurrence_rule IceCube::Rule.daily.count(3) s.add_exception_time(Time.local(2024, 1, 2, 9, 0, 0)) end schedule.to_s ``` -------------------------------- ### Install ice_cube Gem Source: https://github.com/ice-cube-ruby/ice_cube/blob/master/README.md Install the ice_cube gem using the gem command. This is the first step to using the library. ```bash gem install ice_cube ``` -------------------------------- ### Create an IceCube Schedule Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Schedules are built from a start time. Options include setting a duration in seconds or an explicit end time. Inline configuration is supported via a block. ```ruby require 'ice_cube' start = Time.local(2024, 1, 1, 9, 0, 0) # Basic schedule schedule = IceCube::Schedule.new(start) # With duration (each occurrence window is 1 hour) schedule_with_duration = IceCube::Schedule.new(start, duration: 3600) # With explicit end_time (sets duration = end_time - start_time) schedule_with_end = IceCube::Schedule.new(start, end_time: start + 3600) # Block configuration schedule = IceCube::Schedule.new(start) do |s| s.add_recurrence_rule IceCube::Rule.daily.count(5) s.add_exception_time(start + IceCube::ONE_DAY) end schedule.duration # => 0 (or 3600 if end_time set) schedule.start_time # => 2024-01-01 09:00:00 schedule.terminating? # => true (count/until present) ``` -------------------------------- ### Get first 3 occurrences of a daily schedule Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Demonstrates retrieving the first few occurrences of a daily schedule. Ensure the schedule has a terminating rule or is limited by count/until. ```ruby require 'active_support/time' start = Time.zone.local(2024, 1, 1, 9, 0, 0) schedule = IceCube::Schedule.new(start) do |s| s.add_recurrence_rule IceCube::Rule.daily.count(10) s.add_exception_time(start + 2.days) end # All occurrences (terminating schedule only) schedule.all_occurrences # => [Jan 1, Jan 2, Jan 4, Jan 5, Jan 6, Jan 7, Jan 8, Jan 9, Jan 10, Jan 11] # Occurrences up to a closing time schedule.occurrences(start + 5.days) # => [Jan 1, Jan 2, Jan 4, Jan 5] # First / last N schedule.first(3) # => [Jan 1, Jan 2, Jan 4] schedule.last(2) # => [Jan 10, Jan 11] schedule.first # => Jan 1 (single value) ``` -------------------------------- ### Rule to_s Examples Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Generate human-readable string descriptions for recurrence rules. Supports various configurations like weekly intervals, specific days, monthly patterns, and yearly occurrences. ```ruby IceCube::Rule.weekly(2).day(:monday, :wednesday).to_s ``` ```ruby IceCube::Rule.monthly.day_of_week(tuesday: [1, -1]).to_s ``` ```ruby IceCube::Rule.yearly.month_of_year(:march).day_of_month(15).count(5).to_s ``` -------------------------------- ### IceCube::Schedule.new Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Creates a new schedule instance. It can be initialized with a start time and optionally configured with a duration or an end time. Block configuration allows for inline addition of recurrence rules and exceptions. ```APIDOC ## IceCube::Schedule.new — Create a schedule Builds a new schedule anchored at `start_time`. Accepts an optional block for inline configuration. The `:duration` option (seconds) or `:end_time` option sets the duration of each occurrence window. ```ruby require 'ice_cube' start = Time.local(2024, 1, 1, 9, 0, 0) # Basic schedule schedule = IceCube::Schedule.new(start) # With duration (each occurrence window is 1 hour) schedule_with_duration = IceCube::Schedule.new(start, duration: 3600) # With explicit end_time (sets duration = end_time - start_time) schedule_with_end = IceCube::Schedule.new(start, end_time: start + 3600) # Block configuration schedule = IceCube::Schedule.new(start) do |s| s.add_recurrence_rule IceCube::Rule.daily.count(5) s.add_exception_time(start + IceCube::ONE_DAY) end schedule.duration # => 0 (or 3600 if end_time set) schedule.start_time # => 2024-01-01 09:00:00 schedule.terminating? # => true (count/until present) ``` ``` -------------------------------- ### Yearly Recurrence Rule - Basic Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Creates a yearly recurrence rule that fires every year on the same month and day as the schedule's start time. This is the simplest form of yearly recurrence. ```ruby start = Time.local(2024, 3, 15, 9, 0, 0) # Every year on the same month/day as start schedule = IceCube::Schedule.new(start) schedule.add_recurrence_rule IceCube::Rule.yearly ``` -------------------------------- ### Get First or Last Occurrences Source: https://github.com/ice-cube-ruby/ice_cube/blob/master/README.md Retrieve the first or last few occurrences of a schedule. For last occurrences, the schedule must be terminating. ```ruby # or the first (n) occurrences schedule.first(2) # [now, now + 2.days] schedule.first # now # or the last (n) occurrences (if the schedule terminates) schedule.last(2) # [now + 2.days, now + 3.days] schedule.last # now + 3.days ``` -------------------------------- ### Yearly Recurrence Rule - Friday the 13th in October Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Combines yearly recurrence with specific day of month, day of week, and month of year constraints to target specific dates like 'Friday the 13th in October'. Note that the example output is relative to the schedule's start time. ```ruby schedule4 = IceCube::Schedule.new(Time.local(2024, 1, 1)) schedule4.add_recurrence_rule( IceCube::Rule.yearly.day_of_month(13).day(:friday).month_of_year(:october) ) schedule4.first(3) # => [Fri 2023-10-13, Fri 2028-10-13, Fri 2034-10-13] (relative to start) ``` -------------------------------- ### Define and manage exception times and rules Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Schedules can exclude specific times or entire rulesets. Exception times must exactly match an occurrence's start time. Range-based exclusions require external filtering. ```ruby start = Time.local(2024, 3, 1, 8, 0, 0) schedule = IceCube::Schedule.new(start) do |s| s.add_recurrence_rule IceCube::Rule.daily # Exclude a single specific time s.add_exception_time(Time.local(2024, 3, 5, 8, 0, 0)) # Exclude every Monday and Tuesday with an exception rule s.add_exception_rule IceCube::Rule.weekly.day(:monday, :tuesday) end # Inspect what's registered schedule.exception_times # => [2024-03-05 08:00:00] schedule.exception_rules # => [weekly Mon/Tue rule] # Remove an exception time schedule.remove_exception_time(Time.local(2024, 3, 5, 8, 0, 0)) # Range-based exclusion pattern (external filtering) vacations = [ (Time.local(2024, 3, 10)..(Time.local(2024, 3, 17) - 1)) ] occurrences = schedule.occurrences_between( Time.local(2024, 3, 1), Time.local(2024, 3, 31) ).reject { |t| vacations.any? { |r| r.cover?(t) } } ``` -------------------------------- ### Get next and previous occurrences from a reference time Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Retrieves the next or previous occurrences relative to a specified time. Use `next_occurrences` or `previous_occurrences` for multiple values. ```ruby from = start + 3.days schedule.next_occurrence(from) # => Jan 4 09:00:00 schedule.next_occurrences(3, from) # => [Jan 4, Jan 5, Jan 6] schedule.previous_occurrence(from) # => Jan 2 09:00:00 schedule.previous_occurrences(2, from) # => [Jan 1, Jan 2] ``` -------------------------------- ### Add Yearly Recurrence Rule (by Day of Year) Source: https://github.com/ice-cube-ruby/ice_cube/blob/master/README.md Add rules for yearly recurrences based on the day of the year. Supports specifying interval and day numbers from the start or end of the year. ```ruby # every year on the 100th days from the beginning and end of the year schedule.add_recurrence_rule IceCube::Rule.yearly.day_of_year(100, -100) ``` ```ruby # every fourth year on new year's eve schedule.add_recurrence_rule IceCube::Rule.yearly(4).day_of_year(-1) ``` -------------------------------- ### Exception Rules and Times Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Methods for managing exception times and rules to exclude specific moments or recurring patterns from schedule occurrences. Exception times must exactly match an occurrence's start time. ```APIDOC ## Exception rules and exception times Exception times must exactly match an occurrence's start time. For range-based exclusions, filter the returned occurrence array externally. ### `add_exception_time(time)` Adds a specific time to be excluded from occurrences. ### `add_exception_rule(rule)` Adds a recurrence rule to define a pattern of times to be excluded. ### `exception_times` Returns an array of all registered exception times. ### `exception_rules` Returns an array of all registered exception rules. ### `remove_exception_time(time)` Removes a specific time from the exception times. ### Range-based exclusion pattern (external filtering) For exclusions over a range, occurrences should be filtered externally after retrieval. ``` -------------------------------- ### Chaining Multiple Rule Validators Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt An example of chaining multiple validators to create a complex monthly rule: occurrences must be the first Monday of the month, within specific quarters (Jan, Apr, Jul, Oct), and limited to 8 occurrences in total. This demonstrates the power of IceCube's fluent API. ```ruby # Chaining multiple validators schedule = IceCube::Schedule.new(start) schedule.add_recurrence_rule( IceCube::Rule.monthly .day_of_week(monday: [1]) # first Monday .month_of_year(:january, :april, :july, :october) # of each quarter .count(8) ) schedule.all_occurrences # => 8 first-Mondays across Jan/Apr/Jul/Oct ``` -------------------------------- ### Get Next or Previous Occurrences Source: https://github.com/ice-cube-ruby/ice_cube/blob/master/README.md Find the next or previous occurrences relative to a given time. Supports finding multiple occurrences and considering spans. ```ruby # or the next occurrence schedule.next_occurrence(from_time) # defaults to Time.now schedule.next_occurrences(4, from_time) # defaults to Time.now schedule.remaining_occurrences # for terminating schedules # or the previous occurrence schedule.previous_occurrence(from_time) schedule.previous_occurrences(4, from_time) # or include prior occurrences with a duration overlapping from_time schedule.next_occurrences(4, from_time, spans: true) schedule.occurrences_between(from_time, to_time, spans: true) ``` -------------------------------- ### Iterate Through Schedule Occurrences Source: https://github.com/ice-cube-ruby/ice_cube/blob/master/README.md Use an iterator to process each occurrence of a schedule, for example, to print them. This is useful for non-terminating rules when you need to process a finite number of occurrences. ```ruby # or take control and use iteration schedule = IceCube::Schedule.new schedule.add_recurrence_rule IceCube::Rule.daily.until(Date.today + 30) schedule.each_occurrence { |t| puts t } ``` -------------------------------- ### IceCube::Occurrence Object Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Represents an occurrence of a schedule, providing start time, end time, duration, and other related information. ```APIDOC ## `IceCube::Occurrence` An object representing a single occurrence with duration information. ### Attributes - **start_time** (Time) - The start time of the occurrence. - **end_time** (Time) - The end time of the occurrence. - **duration** (Integer) - The duration of the occurrence in seconds. ### Methods - **to_range** - Returns the occurrence as a `Range` object. - **overnight?** - Returns `true` if the occurrence spans across midnight. ### Example ```ruby occ = occurrences.first occ.start_time occ.end_time occ.duration occ.to_range occ.overnight? ``` ``` -------------------------------- ### IceCube::Rule.by_set_pos Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Selects the Nth occurrence within a set of times after all other filters have been applied. Positive numbers count from the start, negative from the end. ```APIDOC ## `.by_set_pos` — Select the Nth occurrence within an interval set (BYSETPOS) After all BYxxx filters are applied within a rule interval, `by_set_pos` selects the Nth entry from the resulting set. Positive positions count from the start; negative from the end. Applies to every frequency (yearly through secondly). ```ruby start = Time.local(2024, 1, 1, 9, 0, 0) # Last weekday of each month schedule = IceCube::Schedule.new(start) schedule.add_recurrence_rule( IceCube::Rule.monthly .day(:monday, :tuesday, :wednesday, :thursday, :friday) .by_set_pos(-1) ) schedule.first(3) # => [Wed 2024-01-31, Thu 2024-02-29, Fri 2024-03-29] ``` ``` -------------------------------- ### Yearly Recurrence Rule - Specific Months Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Defines a yearly recurrence rule that only fires in specified months. The start time's day-of-month is maintained within the selected months. ```ruby schedule2 = IceCube::Schedule.new(start) schedule2.add_recurrence_rule IceCube::Rule.yearly.month_of_year(:january, :february) ``` -------------------------------- ### Get occurrences within a specific date range Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Fetches all occurrences that fall within a given start and end time. The `spans: true` option includes occurrences that overlap the range, even if they start before or end after it. ```ruby schedule.occurrences_between(start + 3.days, start + 6.days) # => [Jan 4, Jan 5, Jan 6] # spans: true — include occurrences whose duration overlaps the query range schedule_dur = IceCube::Schedule.new(start, duration: 3600) schedule_dur.add_recurrence_rule IceCube::Rule.daily schedule_dur.occurrences_between(start - 1800, start + 1800, spans: true) # includes Jan 1 even though start of occurrence is before query window start ``` -------------------------------- ### Schedule with Daily Rule and Exception Time Source: https://github.com/ice-cube-ruby/ice_cube/blob/master/README.md Initialize a schedule with a daily recurrence rule limited to 4 occurrences and add a specific time to be excluded. Requires ActiveSupport for time extensions. ```ruby require 'ice_cube' require 'active_support/time' schedule = IceCube::Schedule.new(now = Time.now) do |s| s.add_recurrence_rule(IceCube::Rule.daily.count(4)) s.add_exception_time(now + 1.day) end ``` -------------------------------- ### Minutely Recurrence Rule with Day of Week Constraint Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Creates a minutely recurrence rule that fires every 90 minutes, specifically targeting the last Tuesday of the month. This combines interval timing with specific day-of-week and position constraints. ```ruby schedule4 = IceCube::Schedule.new(start) schedule4.add_recurrence_rule IceCube::Rule.minutely(90).day_of_week(tuesday: [-1]) ``` -------------------------------- ### Hourly Recurrence Rule with Day Constraint Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Sets up an hourly recurrence rule that fires every 2 hours, but is restricted to only occur on Mondays. This is useful for specific weekday hourly schedules. ```ruby start = Time.local(2024, 6, 1, 0, 0, 0) # Every 2 hours on Mondays only schedule = IceCube::Schedule.new(start) schedule.add_recurrence_rule IceCube::Rule.hourly(2).day(:monday) ``` -------------------------------- ### Customize Global Date Format Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Globally set the time format used for `to_s` output across all Ice Cube schedules and rules. ```ruby IceCube.to_s_time_format ``` -------------------------------- ### Serialize and Deserialize Schedule Objects Source: https://github.com/ice-cube-ruby/ice_cube/blob/master/README.md Use these methods to convert schedule objects to YAML, hash, or ICAL formats and back. YAML and hash serialization are safe and quick. ```ruby yaml = schedule.to_yaml IceCube::Schedule.from_yaml(yaml) ``` ```ruby hash = schedule.to_hash IceCube::Schedule.from_hash(hash) ``` ```ruby ical = schedule.to_ical IceCube::Schedule.from_ical(ical) ``` -------------------------------- ### Add Monthly Recurrence Rule (by Day of Month) Source: https://github.com/ice-cube-ruby/ice_cube/blob/master/README.md Add rules for monthly recurrences based on the day of the month. Skips months too short for the specified day. ```ruby # every month on the first and last days of the month schedule.add_recurrence_rule IceCube::Rule.monthly.day_of_month(1, -1) ``` ```ruby # every other month on the 15th of the month schedule.add_recurrence_rule IceCube::Rule.monthly(2).day_of_month(15) ``` -------------------------------- ### Define Weekly Recurrence Rules Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Weekly rules fire every `interval` weeks. `week_start` controls interval calculation boundaries. `.day` restricts to specific weekdays. Integer day values (0=Sun) can also be used. ```ruby start = Time.local(2024, 1, 1, 10, 0, 0) # Monday schedule = IceCube::Schedule.new(start) # Every week on Monday and Friday schedule.add_recurrence_rule IceCube::Rule.weekly.day(:monday, :friday) # Every other week using integer day values (0=Sun … 6=Sat) schedule2 = IceCube::Schedule.new(start) schedule2.add_recurrence_rule IceCube::Rule.weekly(2).day(1, 5) # Mon, Fri # Monday-based week boundary schedule3 = IceCube::Schedule.new(start) schedule3.add_recurrence_rule IceCube::Rule.weekly(1, :monday).day(:wednesday) schedule.first(4) # => [Mon 2024-01-01, Fri 2024-01-05, Mon 2024-01-08, Fri 2024-01-12] rule = IceCube::Rule.weekly(2).day(:monday, :tuesday) rule.to_ical # => "FREQ=WEEKLY;INTERVAL=2;BYDAY=MO,TU" rule.to_s # => "Every 2 weeks on Mondays and Tuesdays" ``` -------------------------------- ### Rule Validators - Time of Day Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Shows how to constrain rules to specific times of day using `.hour_of_day`, `.minute_of_hour`, and `.second_of_minute`. These validators can be chained for precise timing. ```ruby # .hour_of_day / .minute_of_hour / .second_of_minute IceCube::Rule.daily.hour_of_day(9, 17) # 9 AM and 5 PM every day IceCube::Rule.hourly.minute_of_hour(0, 30) # top and bottom of each hour IceCube::Rule.minutely(1).second_of_minute(0, 30) # twice a minute ``` -------------------------------- ### Select the first weekday of each week Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt This rule defines occurrences for the first weekday (Monday through Friday) of each week. It uses `by_set_pos(1)` to select the first matching day. ```ruby schedule3 = IceCube::Schedule.new(Time.local(2024, 1, 1)) schedule3.add_recurrence_rule( IceCube::Rule.weekly .day(:monday, :tuesday, :wednesday, :thursday, :friday) .by_set_pos(1) ) schedule3.first(3) # => [Mon 2024-01-01, Mon 2024-01-08, Mon 2024-01-15] ``` -------------------------------- ### Secondly Recurrence Rule with Hour Constraint Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Sets up a secondly recurrence rule that fires every 15 seconds, but is further constrained to only occur within the 12th hour (12:00 PM to 12:59 PM). ```ruby schedule3 = IceCube::Schedule.new(start) schedule3.add_recurrence_rule IceCube::Rule.secondly(15).hour_of_day(12) ``` -------------------------------- ### Add Monthly Recurrence Rule (by Nth Weekday) Source: https://github.com/ice-cube-ruby/ice_cube/blob/master/README.md Add rules for monthly recurrences based on the Nth occurrence of a weekday within the month. Supports programmatic convenience with integer mapping. ```ruby # every month on the first and last tuesdays of the month schedule.add_recurrence_rule IceCube::Rule.monthly.day_of_week(tuesday: [1, -1]) ``` ```ruby # every other month on the first monday and last tuesday schedule.add_recurrence_rule IceCube::Rule.monthly(2).day_of_week( monday: [1], tuesday: [-1] ) ``` ```ruby # for programmatic convenience (same as above) schedule.add_recurrence_rule IceCube::Rule.monthly(2).day_of_week(1 => [1], 2 => [-1]) ``` -------------------------------- ### Occurrence Comparisons and Checks Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Compare occurrences directly or check if they intersect. Use `cover?` to determine if a specific time falls within an occurrence's window. ```ruby occ == start occ > start - 1 occ2 = occurrences[1] occ.intersects?(occ2) occ.cover?(start + 900) occ.cover?(start + 1800) ``` ```ruby occ.to_s ``` -------------------------------- ### Serialize Schedules to YAML, Hash, and iCal Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Schedules can be serialized to YAML, Ruby Hash, or iCal string formats for persistence or interoperability. YAML is commonly used with ActiveRecord's `serialize` helper. Rule-level serialization is also supported. ```ruby start = Time.local(2024, 1, 15, 9, 0, 0) schedule = IceCube::Schedule.new(start) do |s| s.add_recurrence_rule IceCube::Rule.weekly.day(:monday, :wednesday, :friday).count(12) s.add_exception_time(Time.local(2024, 2, 5, 9, 0, 0)) end # YAML round-trip yaml = schedule.to_yaml restored = IceCube::Schedule.from_yaml(yaml) restored.first(3) == schedule.first(3) # => true # Hash round-trip hash = schedule.to_hash # => { start_time: ..., rrules: [...], extimes: [...], rtimes: [], ... } restored2 = IceCube::Schedule.from_hash(hash) # iCal round-trip (partial — no timezone in datetime strings) ical = schedule.to_ical # => "DTSTART:20240115T090000\nRRULE:FREQ=WEEKLY;COUNT=12;BYDAY=MO,WE,FR\nEXDATE:20240205T090000" restored3 = IceCube::Schedule.from_ical(ical) # Rule-level serialization rule = IceCube::Rule.daily(2).day_of_week(tuesday: [1, -1], wednesday: [2]) rule.to_ical # => "FREQ=DAILY;INTERVAL=2;BYDAY=1TU,-1TU,2WE" rule.to_s # => "Every 2 days on the 1st and last Tuesdays and the 2nd Wednesday" rule.to_hash # => { rule_type: "IceCube::DailyRule", interval: 2, validations: { day_of_week: ... } } IceCube::Rule.from_hash(rule.to_hash) == rule # => true # ActiveRecord integration # Migration: add_column :tasks, :schedule, :text # Model: # class Task < ActiveRecord::Base # include IceCube # serialize :schedule, IceCube::Schedule # end ``` -------------------------------- ### Add Recurrence Rule with BYSETPOS Source: https://github.com/ice-cube-ruby/ice_cube/blob/master/README.md Use BYSETPOS to select the Nth occurrence within each interval after other filters are applied. RFC 5545 requires it with another BYxxx rule part, but IceCube allows it independently. ```ruby # last weekday of the month schedule.add_recurrence_rule( IceCube::Rule.monthly.day(:monday, :tuesday, :wednesday, :thursday, :friday).by_set_pos(-1) ) ``` ```ruby # second occurrence in each day's expanded set schedule.add_recurrence_rule( IceCube::Rule.daily.hour_of_day(9, 17).by_set_pos(2) ) ``` -------------------------------- ### Querying Occurrences Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Methods for retrieving occurrences from a schedule, including all occurrences, occurrences within a range, first/last N occurrences, and next/previous occurrences relative to a given time. Note that methods like `all_occurrences` and `last` require a terminating rule. ```APIDOC ## Querying Occurrences All query methods operate on the fully materialized rule set. Methods that could iterate forever (`all_occurrences`, `last`) require at least one terminating rule (`.count` or `.until`) and raise `ArgumentError` otherwise. ### `all_occurrences` Retrieves all occurrences for a schedule. Requires a terminating rule. ### `occurrences(end_time)` Retrieves occurrences up to a specified `end_time`. ### `first(n)` Retrieves the first `n` occurrences. ### `last(n)` Retrieves the last `n` occurrences. Requires a terminating rule. ### `first` Retrieves the single first occurrence. ### `next_occurrence(from_time)` Retrieves the next occurrence after `from_time`. ### `next_occurrences(n, from_time)` Retrieves the next `n` occurrences after `from_time`. ### `previous_occurrence(from_time)` Retrieves the previous occurrence before `from_time`. ### `previous_occurrences(n, from_time)` Retrieves the previous `n` occurrences before `from_time`. ### `remaining_occurrences` Retrieves occurrences from `Time.now` onward. ### `occurrences_between(start_time, end_time)` Retrieves occurrences between `start_time` and `end_time`. ### `occurs_at?(time)` Checks if an occurrence exists exactly at the given `time`. ### `occurs_on?(date)` Checks if any occurrence falls on the given `date`. ### `occurs_between?(start_time, end_time)` Checks if any occurrence falls within the `start_time` and `end_time` range. ### `occurrences_between(start_time, end_time, spans: true)` Retrieves occurrences between `start_time` and `end_time`, including those whose duration overlaps the query range. ``` -------------------------------- ### Schedule Serialization Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Schedules can be serialized to YAML, Ruby Hash, or iCal string formats, and restored from these formats. This is useful for storage and transfer. ```APIDOC ## `Schedule#to_yaml` and `Schedule.from_yaml` Serializes the schedule to a YAML string and restores it. ### Method `to_yaml` returns a YAML string. `from_yaml(yaml_string)` returns a Schedule object. ### Example ```ruby yaml = schedule.to_yaml restored = IceCube::Schedule.from_yaml(yaml) ``` ## `Schedule#to_hash` and `Schedule.from_hash` Serializes the schedule to a Ruby Hash and restores it. ### Method `to_hash` returns a Hash. `from_hash(hash)` returns a Schedule object. ### Example ```ruby hash = schedule.to_hash restored = IceCube::Schedule.from_hash(hash) ``` ## `Schedule#to_ical` and `Schedule.from_ical` Serializes the schedule to an iCal string and restores it. ### Method `to_ical` returns an iCal string. `from_ical(ical_string)` returns a Schedule object. ### Example ```ruby ical = schedule.to_ical restored = IceCube::Schedule.from_ical(ical) ``` ``` -------------------------------- ### Rule Validator - Day of Month Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Shows how to use `.day_of_month` to specify exact calendar dates within a month. Negative numbers count from the end of the month, useful for rules like 'the last day'. ```ruby # .day_of_month — specific calendar dates; negative = from end of month IceCube::Rule.monthly.day_of_month(1, 15, -1) ``` -------------------------------- ### Schedule with Duration and Occurring Checks Source: https://github.com/ice-cube-ruby/ice_cube/blob/master/README.md Define a schedule with an explicit duration and check if it is occurring at a specific time or within a time range. ```ruby # or give the schedule a duration and ask if occurring_at? schedule = IceCube::Schedule.new(now, duration: 3600) schedule.add_recurrence_rule IceCube::Rule.daily schedule.occurring_at?(now + 1800) # true schedule.occurring_between?(t1, t2) # using end_time also sets the duration schedule = IceCube::Schedule.new(start = Time.now, end_time: start + 3600) schedule.add_recurrence_rule IceCube::Rule.daily schedule.occurring_at?(start + 3599) # true schedule.occurring_at?(start + 3600) # false ``` -------------------------------- ### Yearly Recurrence Rule - Day of Year Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Creates a yearly recurrence rule with a specified interval, targeting a specific day of the year. Negative values count from the end of the year, useful for fixed dates like New Year's Eve. ```ruby schedule3 = IceCube::Schedule.new(Time.local(2024, 1, 1)) schedule3.add_recurrence_rule IceCube::Rule.yearly(4).day_of_year(-1) ``` -------------------------------- ### Define Monthly Recurrence Rules Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Monthly rules fire every `interval` months. `.day_of_month` pins to specific calendar dates, while `.day_of_week` selects the Nth weekday occurrence. Months too short for the specified day are skipped. ```ruby start = Time.local(2024, 1, 1, 12, 0, 0) # 1st and last day of every month schedule = IceCube::Schedule.new(start) schedule.add_recurrence_rule IceCube::Rule.monthly.day_of_month(1, -1) # Every other month on the 15th schedule2 = IceCube::Schedule.new(start) schedule2.add_recurrence_rule IceCube::Rule.monthly(2).day_of_month(15) # First and last Tuesday of every month schedule3 = IceCube::Schedule.new(start) schedule3.add_recurrence_rule IceCube::Rule.monthly.day_of_week(tuesday: [1, -1]) ``` -------------------------------- ### IceCube::Rule.weekly Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Defines a weekly recurrence rule. It fires every `interval` weeks, with an optional `week_start` parameter to define the week's boundary. Specific weekdays can be selected using the `.day` method. ```APIDOC ## IceCube::Rule.weekly — Weekly recurrence rule Fires every `interval` weeks. An optional `week_start` symbol (default `:sunday`) controls the boundary used for weekly interval calculations. Use `.day` to restrict to specific weekdays. ```ruby start = Time.local(2024, 1, 1, 10, 0, 0) # Monday schedule = IceCube::Schedule.new(start) # Every week on Monday and Friday schedule.add_recurrence_rule IceCube::Rule.weekly.day(:monday, :friday) # Every other week using integer day values (0=Sun … 6=Sat) schedule2 = IceCube::Schedule.new(start) schedule2.add_recurrence_rule IceCube::Rule.weekly(2).day(1, 5) # Mon, Fri # Monday-based week boundary schedule3 = IceCube::Schedule.new(start) schedule3.add_recurrence_rule IceCube::Rule.weekly(1, :monday).day(:wednesday) schedule.first(4) # => [Mon 2024-01-01, Fri 2024-01-05, Mon 2024-01-08, Fri 2024-01-12] rule = IceCube::Rule.weekly(2).day(:monday, :tuesday) rule.to_ical # => "FREQ=WEEKLY;INTERVAL=2;BYDAY=MO,TU" rule.to_s # => "Every 2 weeks on Mondays and Tuesdays" ``` ``` -------------------------------- ### IceCube::Rule.hourly / .minutely / .secondly Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Defines sub-daily recurrence rules that fire at fixed intervals in hours, minutes, or seconds. These can be combined with other validators to constrain firing times. ```APIDOC ## `IceCube::Rule.hourly` / `.minutely` / `.secondly` — Sub-daily recurrence rules These rules fire at fixed intervals measured in hours, minutes, or seconds. Combine with `.day`, `.hour_of_day`, `.minute_of_hour`, or `.second_of_minute` to constrain when firings happen. ```ruby start = Time.local(2024, 6, 1, 0, 0, 0) # Every 2 hours on Mondays only schedule = IceCube::Schedule.new(start) schedule.add_recurrence_rule IceCube::Rule.hourly(2).day(:monday) # Every 10 minutes, limited by count schedule2 = IceCube::Schedule.new(start) schedule2.add_recurrence_rule IceCube::Rule.minutely(10).count(6) schedule2.all_occurrences # => [00:00, 00:10, 00:20, 00:30, 00:40, 00:50] # Every 15 seconds between 12:00–12:59 schedule3 = IceCube::Schedule.new(start) schedule3.add_recurrence_rule IceCube::Rule.secondly(15).hour_of_day(12) # Every 90 minutes on the last Tuesday of the month schedule4 = IceCube::Schedule.new(start) schedule4.add_recurrence_rule IceCube::Rule.minutely(90).day_of_week(tuesday: [-1]) ``` ``` -------------------------------- ### Occurrence Objects with Duration: `IceCube::Occurrence` Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Occurrences returned by query methods are `IceCube::Occurrence` objects. These delegate to `start_time` and also provide `end_time` and `duration` for schedules with a defined duration. ```ruby start = Time.local(2024, 4, 1, 10, 0, 0) schedule = IceCube::Schedule.new(start, duration: 1800) schedule.add_recurrence_rule IceCube::Rule.daily.count(3) occurrences = schedule.all_occurrences occ = occurrences.first occ.start_time # => 2024-04-01 10:00:00 occ.end_time # => 2024-04-01 10:30:00 occ.duration # => 1800 occ.to_range # => 2024-04-01 10:00:00..2024-04-01 10:30:00 occ.overnight? # => false ``` -------------------------------- ### Rule Validator - Day of Week Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Illustrates restricting a daily rule to specific weekdays using their symbolic names (e.g., :monday) or integer representations (0-6). ```ruby # .day — restrict to specific weekdays (symbol or integer 0–6) IceCube::Rule.daily.day(:monday, :wednesday, :friday) IceCube::Rule.weekly.day(1, 3, 5) ``` -------------------------------- ### Add Daily Recurrence Rule Source: https://github.com/ice-cube-ruby/ice_cube/blob/master/README.md Add rules for daily recurrences to a schedule. Supports specifying an interval for non-daily occurrences. ```ruby # every day schedule.add_recurrence_rule IceCube::Rule.daily ``` ```ruby # every third day schedule.add_recurrence_rule IceCube::Rule.daily(3) ``` -------------------------------- ### Add Yearly Recurrence Rule (by Month of Year) Source: https://github.com/ice-cube-ruby/ice_cube/blob/master/README.md Add rules for yearly recurrences based on the month of the year. Supports specifying interval and month names or numbers. ```ruby # every year on the same day as start_time but in january and february schedule.add_recurrence_rule IceCube::Rule.yearly.month_of_year(:january, :february) ``` ```ruby # every third year in march schedule.add_recurrence_rule IceCube::Rule.yearly(3).month_of_year(:march) ``` ```ruby # for programmatic convenience (same as above) schedule.add_recurrence_rule IceCube::Rule.yearly(3).month_of_year(3) ``` -------------------------------- ### Add Minutely Recurrence Rule Source: https://github.com/ice-cube-ruby/ice_cube/blob/master/README.md Add rules for minutely recurrences. Supports specifying interval in minutes and combining with other rules like day_of_week. ```ruby # every 10 minutes schedule.add_recurrence_rule IceCube::Rule.minutely(10) ``` ```ruby # every hour and a half, on the last tuesday of the month schedule.add_recurrence_rule IceCube::Rule.minutely(90).day_of_week(tuesday: [-1]) ``` -------------------------------- ### IceCube::Rule.daily Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Defines a daily recurrence rule. By default, it fires every day. This can be modified by specifying an interval for days and chaining BYxxx validators to refine the rule. ```APIDOC ## IceCube::Rule.daily — Daily recurrence rule Fires every `interval` days from the schedule's start time. Chain BYxxx validators to restrict which days qualify. ```ruby start = Time.local(2024, 3, 1, 8, 0, 0) schedule = IceCube::Schedule.new(start) # Every day schedule.add_recurrence_rule IceCube::Rule.daily # Every 3 days, limited to 4 occurrences schedule.add_recurrence_rule IceCube::Rule.daily(3).count(4) # Every day, only on weekdays schedule2 = IceCube::Schedule.new(start) schedule2.add_recurrence_rule IceCube::Rule.daily.day(:monday, :tuesday, :wednesday, :thursday, :friday) schedule2.first(5) # => [Mon 2024-03-04 08:00:00, Tue 2024-03-05, Wed 2024-03-06, Thu 2024-03-07, Fri 2024-03-08] ``` ``` -------------------------------- ### Rule Validator - Month of Year Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Demonstrates restricting yearly rules to specific months using their symbolic names (e.g., :march) or integer representations (1-12). ```ruby # .month_of_year — restrict to specific months (symbol or integer 1–12) IceCube::Rule.yearly.month_of_year(:march, :september) IceCube::Rule.yearly.month_of_year(3, 9) ``` -------------------------------- ### List Occurrences of a Schedule Source: https://github.com/ice-cube-ruby/ice_cube/blob/master/README.md Retrieve all occurrences of a schedule up to a specified end time, or all occurrences if the schedule is terminating. ```ruby # list occurrences until end_time (end_time is needed for non-terminating rules) occurrences = schedule.occurrences(end_time) # [now] # or all of the occurrences (only for terminating schedules) occurrences = schedule.all_occurrences # [now, now + 2.days, now + 3.days] ``` -------------------------------- ### Check if a Schedule Occurs at a Specific Time or Day Source: https://github.com/ice-cube-ruby/ice_cube/blob/master/README.md Verify if a specific point in time or a whole day falls within the schedule's occurrences. ```ruby # or check just a single time schedule.occurs_at?(now + 1.day) # false schedule.occurs_at?(now + 2.days) # true # or check just a single day schedule.occurs_on?(Date.today) # true ``` -------------------------------- ### Add Hourly Recurrence Rule Source: https://github.com/ice-cube-ruby/ice_cube/blob/master/README.md Add rules for hourly recurrences. Can specify interval and days of the week. Unspecified smaller time components inherit from the schedule's start_time. ```ruby # every hour on the same minute and second as start date schedule.add_recurrence_rule IceCube::Rule.hourly ``` ```ruby # every other hour, on mondays schedule.add_recurrence_rule IceCube::Rule.hourly(2).day(:monday) ``` -------------------------------- ### Select the second occurrence of 9 AM or 5 PM daily Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt This rule selects the second occurrence within the specified hours (9 AM and 5 PM) each day. In this case, it will select 5 PM. ```ruby schedule2 = IceCube::Schedule.new(start) schedule2.add_recurrence_rule( IceCube::Rule.daily.hour_of_day(9, 17).by_set_pos(2) ) schedule2.first(3) # => [2024-01-01 17:00, 2024-01-02 17:00, 2024-01-03 17:00] ``` -------------------------------- ### Convert Rule to ICAL or String Representation Source: https://github.com/ice-cube-ruby/ice_cube/blob/master/README.md Generate ICAL formatted strings or human-readable string representations of recurrence rules. Useful for external systems or display. ```ruby rule = IceCube::Rule.daily(2).day_of_week(tuesday: [1, -1], wednesday: [2]) rule.to_ical # 'FREQ=DAILY;INTERVAL=2;BYDAY=1TU,-1TU,2WE' ``` ```ruby rule.to_s # 'Every 2 days on the last and 1st Tuesdays and the 2nd Wednesday' ``` -------------------------------- ### Add Weekly Recurrence Rule Source: https://github.com/ice-cube-ruby/ice_cube/blob/master/README.md Add rules for weekly recurrences. Can specify interval, days of the week, and the first weekday. ```ruby # every week schedule.add_recurrence_rule IceCube::Rule.weekly ``` ```ruby # every other week on monday and tuesday schedule.add_recurrence_rule IceCube::Rule.weekly(2).day(:monday, :tuesday) ``` ```ruby # for programmatic convenience (same as above) schedule.add_recurrence_rule IceCube::Rule.weekly(2).day(1, 2) ``` ```ruby # specifying a weekly interval with a different first weekday (defaults to Sunday) schedule.add_recurrence_rule IceCube::Rule.weekly(1, :monday) ``` -------------------------------- ### Rule Validator - Day of Week Position Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Demonstrates the `.day_of_week` validator for monthly rules, allowing selection of the Nth occurrence of a specific weekday within the month, such as the first and last Friday. ```ruby # .day_of_week — Nth occurrence of a weekday in the period IceCube::Rule.monthly.day_of_week(friday: [1, -1]) # first & last Friday ``` -------------------------------- ### Define Daily Recurrence Rules Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Daily rules fire every `interval` days. BYxxx validators can restrict qualifying days. The `.count` method limits the total number of occurrences. ```ruby start = Time.local(2024, 3, 1, 8, 0, 0) schedule = IceCube::Schedule.new(start) # Every day schedule.add_recurrence_rule IceCube::Rule.daily # Every 3 days, limited to 4 occurrences schedule.add_recurrence_rule IceCube::Rule.daily(3).count(4) # Every day, only on weekdays schedule2 = IceCube::Schedule.new(start) schedule2.add_recurrence_rule IceCube::Rule.daily.day(:monday, :tuesday, :wednesday, :thursday, :friday) schedule2.first(5) # => [Mon 2024-03-04 08:00:00, Tue 2024-03-05, Wed 2024-03-06, Thu 2024-03-07, Fri 2024-03-08] ``` -------------------------------- ### Adding One-off Recurrence Times Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Pinpoints individual times to include in the schedule regardless of any recurrence rule. You can also remove specific times. ```APIDOC ## `Schedule#add_recurrence_time` Adds a specific time to be included in the schedule. ### Method `add_recurrence_time(time)` ### Parameters - **time** (Time) - The specific time to add. ### Example ```ruby start = Time.local(2024, 1, 1, 9, 0, 0) schedule = IceCube::Schedule.new(start) schedule.add_recurrence_time(Time.local(2024, 6, 15, 10, 0, 0)) ``` ## `Schedule#remove_recurrence_time` Removes a specific time from the schedule. ### Method `remove_recurrence_time(time)` ### Parameters - **time** (Time) - The specific time to remove. ### Example ```ruby schedule.remove_recurrence_time(Time.local(2024, 6, 15, 10, 0, 0)) ``` ``` -------------------------------- ### Add Specific Recurrence Times with `add_recurrence_time` Source: https://context7.com/ice-cube-ruby/ice_cube/llms.txt Pinpoint individual times to include in a schedule, independent of any recurrence rules. These times can be added to or removed from a schedule. ```ruby start = Time.local(2024, 1, 1, 9, 0, 0) schedule = IceCube::Schedule.new(start) # No recurring rule — just specific times schedule.add_recurrence_time(Time.local(2024, 6, 15, 10, 0, 0)) schedule.add_recurrence_time(Time.local(2024, 12, 25, 10, 0, 0)) schedule.recurrence_times # => [2024-06-15 10:00:00, 2024-12-25 10:00:00] # Mix with rules schedule.add_recurrence_rule IceCube::Rule.weekly.day(:friday) # Now fires every Friday AND on Jun 15 and Dec 25 # Remove a specific time schedule.remove_recurrence_time(Time.local(2024, 6, 15, 10, 0, 0)) ```