{"id":13394939,"url":"https://github.com/ice-cube-ruby/ice_cube","last_synced_at":"2025-05-13T00:15:26.502Z","repository":{"id":835831,"uuid":"556060","full_name":"ice-cube-ruby/ice_cube","owner":"ice-cube-ruby","description":"Ruby Date Recurrence Library - Allows easy creation of recurrence rules and fast querying","archived":false,"fork":false,"pushed_at":"2024-07-19T13:13:38.000Z","size":4420,"stargazers_count":2443,"open_issues_count":62,"forks_count":358,"subscribers_count":38,"default_branch":"master","last_synced_at":"2025-05-13T00:15:11.403Z","etag":null,"topics":["ruby"],"latest_commit_sha":null,"homepage":"","language":"Ruby","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":"Unmaintained","scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ice-cube-ruby.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2010-03-10T15:27:10.000Z","updated_at":"2025-05-12T16:13:05.000Z","dependencies_parsed_at":"2023-07-05T15:16:39.843Z","dependency_job_id":"cff25791-2eda-42aa-898d-5b3151aa0904","html_url":"https://github.com/ice-cube-ruby/ice_cube","commit_stats":{"total_commits":868,"total_committers":84,"mean_commits":"10.333333333333334","dds":0.7096774193548387,"last_synced_commit":"ee21ea6772bf7cf5a80c63e2f880046e30839744"},"previous_names":["seejohnrun/ice_cube"],"tags_count":96,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ice-cube-ruby%2Fice_cube","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ice-cube-ruby%2Fice_cube/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ice-cube-ruby%2Fice_cube/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ice-cube-ruby%2Fice_cube/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ice-cube-ruby","download_url":"https://codeload.github.com/ice-cube-ruby/ice_cube/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253843225,"owners_count":21972874,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ruby"],"created_at":"2024-07-30T17:01:36.797Z","updated_at":"2025-05-13T00:15:26.460Z","avatar_url":"https://github.com/ice-cube-ruby.png","language":"Ruby","readme":"# ice_cube - Easy schedule expansion\n\n[![Tests](https://github.com/seejohnrun/ice_cube/actions/workflows/tests.yaml/badge.svg)](https://github.com/seejohnrun/ice_cube/actions/workflows/tests.yaml)\n[![Gem Version](https://badge.fury.io/rb/ice_cube.svg)](http://badge.fury.io/rb/ice_cube)\n[![Ruby Style Guide](https://img.shields.io/badge/code_style-standard-brightgreen.svg)](https://github.com/testdouble/standard)\n\n```bash\ngem install ice_cube\n```\n\nice_cube is a ruby library for easily handling repeated events (schedules).\nThe API is modeled after [iCalendar events][ical-3.6.1], in a pleasant Ruby\nsyntax. The power lies in the ability to specify multiple rules, and have\nice_cube quickly figure out whether the schedule falls on a certain date\n(.occurs_on?), or what times it occurs at (.occurrences, .first,\n.all_occurrences).\n\nImagine you want:\n\n\u003e Every friday the 13th that falls in October\n\nYou would write:\n\n```ruby\nschedule = IceCube::Schedule.new\nschedule.add_recurrence_rule(\n  IceCube::Rule.yearly.day_of_month(13).day(:friday).month_of_year(:october)\n)\n```\n\n---\n\n## Quick Introductions\n\n* Presentation from Lone Star Ruby Conf ([slides][ice_cube-lone_star_pdf], [YouTube](https://youtu.be/dOMW0WcvvRc))\n* [Quick Introduction][ice_cube-ruby_nyc_pdf]\n* [Documentation Website][ice_cube-docs]\n\n---\n\nWith ice_cube, you can specify (in increasing order of precedence):\n\n* Recurrence Rules - Rules on how to include recurring times in a schedule\n* Recurrence Times - To specifically include in a schedule\n* Exception Times - To specifically exclude from a schedule\n\nExample: Specifying a recurrence with an exception time. Requires \"rails/activesupport\" (`gem install 'activesupport'`).\n\n\n```ruby\nrequire 'ice_cube'\nrequire 'active_support/time'\n\nschedule = IceCube::Schedule.new(now = Time.now) do |s|\n  s.add_recurrence_rule(IceCube::Rule.daily.count(4))\n  s.add_exception_time(now + 1.day)\nend\n\n# list occurrences until end_time (end_time is needed for non-terminating rules)\noccurrences = schedule.occurrences(end_time) # [now]\n\n# or all of the occurrences (only for terminating schedules)\noccurrences = schedule.all_occurrences # [now, now + 2.days, now + 3.days]\n\n# or check just a single time\nschedule.occurs_at?(now + 1.day)  # false\nschedule.occurs_at?(now + 2.days) # true\n\n# or check just a single day\nschedule.occurs_on?(Date.today) # true\n\n# or check whether it occurs between two dates\nschedule.occurs_between?(now, now + 30.days)          # true\nschedule.occurs_between?(now + 4.days, now + 30.days) # false\n\n# or the first (n) occurrences\nschedule.first(2) # [now, now + 2.days]\nschedule.first    # now\n\n# or the last (n) occurrences (if the schedule terminates)\nschedule.last(2) # [now + 2.days, now + 3.days]\nschedule.last    # now + 3.days\n\n# or the next occurrence\nschedule.next_occurrence(from_time)     # defaults to Time.now\nschedule.next_occurrences(4, from_time) # defaults to Time.now\nschedule.remaining_occurrences          # for terminating schedules\n\n# or the previous occurrence\nschedule.previous_occurrence(from_time)\nschedule.previous_occurrences(4, from_time)\n\n# or include prior occurrences with a duration overlapping from_time\nschedule.next_occurrences(4, from_time, spans: true)\nschedule.occurrences_between(from_time, to_time, spans: true)\n\n# or give the schedule a duration and ask if occurring_at?\nschedule = IceCube::Schedule.new(now, duration: 3600)\nschedule.add_recurrence_rule IceCube::Rule.daily\nschedule.occurring_at?(now + 1800) # true\nschedule.occurring_between?(t1, t2)\n\n# using end_time also sets the duration\nschedule = IceCube::Schedule.new(start = Time.now, end_time: start + 3600)\nschedule.add_recurrence_rule IceCube::Rule.daily\nschedule.occurring_at?(start + 3599) # true\nschedule.occurring_at?(start + 3600) # false\n\n# take control and use iteration\nschedule = IceCube::Schedule.new\nschedule.add_recurrence_rule IceCube::Rule.daily.until(Date.today + 30)\nschedule.each_occurrence { |t| puts t }\n```\n\nThe reason that schedules have durations and not individual rules, is to\nmaintain compatibility with the ical\nRFC: http://www.kanzaki.com/docs/ical/rrule.html\n\nTo limit schedules use `count` or `until` on the recurrence rules. Setting `end_time` on the schedule just sets the duration (from the start time) for each occurrence.\n\n---\n\n## Time Zones and ActiveSupport vs. Standard Ruby Time Classes\n\nice_cube works great without ActiveSupport but only supports the environment's\nsingle \"local\" time zone (`ENV['TZ']`) or UTC. To correctly support multiple\ntime zones (especially for DST), you should require 'active_support/time'.\n\nA schedule's occurrences will be returned in the same class and time zone as\nthe schedule's start_time. Schedule start times are supported as:\n\n* Time.local (default when no time is specified)\n* Time.utc\n* ActiveSupport::TimeWithZone (with `Time.zone.now`, `Time.zone.local`, `time.in_time_zone(tz)`)\n* DateTime (deprecated) and Date are converted to a Time.local\n\n---\n\n## Persistence\n\nice_cube implements its own hash-based .to_yaml, so you can quickly (and\nsafely) serialize schedule objects in and out of your data store\n\nIt also supports partial serialization to/from `ICAL`. Parsing datetimes with time zone information is not currently supported.\n\n``` ruby\nyaml = schedule.to_yaml\nIceCube::Schedule.from_yaml(yaml)\n\nhash = schedule.to_hash\nIceCube::Schedule.from_hash(hash)\n\nical = schedule.to_ical\nIceCube::Schedule.from_ical(ical)\n```\n\n---\n\n## Using your words\n\nice_cube can provide ical or string representations of individual rules, or the\nwhole schedule.\n\n```ruby\nrule = IceCube::Rule.daily(2).day_of_week(tuesday: [1, -1], wednesday: [2])\n\nrule.to_ical # 'FREQ=DAILY;INTERVAL=2;BYDAY=1TU,-1TU,2WE'\n\nrule.to_s # 'Every 2 days on the last and 1st Tuesdays and the 2nd Wednesday'\n```\n\n---\n\n## Some types of Rules\n\nThere are many types of recurrence rules that can be added to a schedule:\n\n### Daily\n\n```ruby\n# every day\nschedule.add_recurrence_rule IceCube::Rule.daily\n\n# every third day\nschedule.add_recurrence_rule IceCube::Rule.daily(3)\n```\n\n### Weekly\n\n```ruby\n# every week\nschedule.add_recurrence_rule IceCube::Rule.weekly\n\n# every other week on monday and tuesday\nschedule.add_recurrence_rule IceCube::Rule.weekly(2).day(:monday, :tuesday)\n\n# for programmatic convenience (same as above)\nschedule.add_recurrence_rule IceCube::Rule.weekly(2).day(1, 2)\n\n# specifying a weekly interval with a different first weekday (defaults to Sunday)\nschedule.add_recurrence_rule IceCube::Rule.weekly(1, :monday)\n```\n\n### Monthly (by day of month)\n\n```ruby\n# every month on the first and last days of the month\nschedule.add_recurrence_rule IceCube::Rule.monthly.day_of_month(1, -1)\n\n# every other month on the 15th of the month\nschedule.add_recurrence_rule IceCube::Rule.monthly(2).day_of_month(15)\n```\n\nMonthly rules will skip months that are too short for the specified day of\nmonth (e.g. no occurrences in February for `day_of_month(31)`).\n\n### Monthly (by day of Nth week)\n\n```ruby\n# every month on the first and last tuesdays of the month\nschedule.add_recurrence_rule IceCube::Rule.monthly.day_of_week(tuesday: [1, -1])\n\n# every other month on the first monday and last tuesday\nschedule.add_recurrence_rule IceCube::Rule.monthly(2).day_of_week(\n  monday: [1],\n  tuesday: [-1]\n)\n\n# for programmatic convenience (same as above)\nschedule.add_recurrence_rule IceCube::Rule.monthly(2).day_of_week(1 =\u003e [1], 2 =\u003e [-1])\n```\n\n### Yearly (by day of year)\n\n```ruby\n# every year on the 100th days from the beginning and end of the year\nschedule.add_recurrence_rule IceCube::Rule.yearly.day_of_year(100, -100)\n\n# every fourth year on new year's eve\nschedule.add_recurrence_rule IceCube::Rule.yearly(4).day_of_year(-1)\n```\n\n### Yearly (by month of year)\n\n```ruby\n# every year on the same day as start_time but in january and february\nschedule.add_recurrence_rule IceCube::Rule.yearly.month_of_year(:january, :february)\n\n# every third year in march\nschedule.add_recurrence_rule IceCube::Rule.yearly(3).month_of_year(:march)\n\n# for programmatic convenience (same as above)\nschedule.add_recurrence_rule IceCube::Rule.yearly(3).month_of_year(3)\n```\n\n### Hourly (by hour of day)\n\n```ruby\n# every hour on the same minute and second as start date\nschedule.add_recurrence_rule IceCube::Rule.hourly\n\n# every other hour, on mondays\nschedule.add_recurrence_rule IceCube::Rule.hourly(2).day(:monday)\n```\n\n### Minutely (every N minutes)\n\n```ruby\n# every 10 minutes\nschedule.add_recurrence_rule IceCube::Rule.minutely(10)\n\n# every hour and a half, on the last tuesday of the month\nschedule.add_recurrence_rule IceCube::Rule.minutely(90).day_of_week(tuesday: [-1])\n```\n\n### Secondly (every N seconds)\n\n```ruby\n# every second\nschedule.add_recurrence_rule IceCube::Rule.secondly\n\n# every 15 seconds between 12:00 - 12:59\nschedule.add_recurrence_rule IceCube::Rule.secondly(15).hour_of_day(12)\n```\n\n---\n\n## recurring_select\n\nThe team over at [GetJobber](http://getjobber.com/) have open-sourced\nRecurringSelect, which makes working with IceCube easier in a Rails app\nvia some nice helpers.\n\nCheck it out at\nhttps://github.com/GetJobber/recurring_select\n\n---\n\n## Contributors\n\nhttps://github.com/ice-cube-ruby/ice_cube/graphs/contributors\n\n---\n\n## Issues?\n\nUse the GitHub [issue tracker][ice_cube-issues]\n\n## Contributing\n\n* Contributions are welcome - I use GitHub for issue\n\ttracking (accompanying failing tests are awesome) and feature requests\n* Submit via fork and pull request (include tests)\n* If you're working on something major, shoot me a message beforehand\n\n\n\n[ical-3.6.1]: https://tools.ietf.org/html/rfc5545#section-3.6.1\n[ice_cube-lone_star_pdf]: https://ice-cube-ruby.github.io/ice_cube/static/lsrc_ice_cube.pdf\n[ice_cube-ruby_nyc_pdf]: https://ice-cube-ruby.github.io/ice_cube/static/ice_cube_ruby_nyc.pdf\n[ice_cube-docs]: https://ice-cube-ruby.github.io/ice_cube/\n[ice_cube-issues]: https://github.com/ice-cube-ruby/ice_cube/issues\n","funding_links":[],"categories":["Ruby"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fice-cube-ruby%2Fice_cube","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fice-cube-ruby%2Fice_cube","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fice-cube-ruby%2Fice_cube/lists"}