установка драгоценного камня Ice_cube
Ice_cube — это библиотека Ruby для удобной обработки повторяющихся событий (расписаний). API создан по образцу событий iCalendar и имеет приятный синтаксис Ruby. Сила заключается в возможности указать несколько правил и позволить Ice_cube быстро определить, приходится ли расписание на определенную дату (.occurs_on?) или в какое время оно происходит (.occurrences, .first, .all_occurrences).
Представьте, что вы хотите:
Каждую пятницу 13-го октября.
Вы бы написали:
расписание = IceCube::Schedule.newschedule.add_recurrence_rule( IceCube::Rule.yearly.day_of_month(13).day(:пятница).month_of_year(:октябрь))
Презентация с Lone Star Ruby Conf (слайды, YouTube)
Краткое введение
Веб-сайт документации
С помощью Ice_cube вы можете указать (в порядке возрастания приоритета):
Правила повторения — правила включения повторяющихся значений в расписание.
Время повторения – специально включить в расписание.
Время исключений – специальное исключение из расписания.
Пример: указание повторения с временем исключения. Требуется «rails/activesupport» ( gem install 'activesupport'
).
требуется '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# список вхождений до end_time (конечное_время необходимо для непрерывных правил)occurrences = Schedule.occurrences(end_time) # [now]# или все вхождения (только для завершающих расписаний) вхождения = Schedule.all_occurrences # [сейчас, сейчас + 2.дни, сейчас + 3.дни]# или отметьте только один timeschedule.occurs_at?(now + 1.day) # falseschedule.occurs_at?(now + 2.days) # true# или проверьте только один деньchedule.occurs_on?(Date.today) # true# или проверьте, происходит ли это между двумя dateschedule.occurs_between?(сейчас, сейчас + 30.дней) # trueschedule.occurs_between?(сейчас + 4.days, now + 30.days) # false# или первое (n) вхождениеsschedule.first(2) # [now, now + 2.days]schedule.first # now# или последнее (n) вхождение (если расписание завершается)schedule.last(2) # [now + 2.days, now + 3.days]schedule.last # now + 3.days# или следующее eventschedule.next_occurrence(from_time) # по умолчанию Time.nowschedule.next_occurrence(4, from_time) # по умолчанию Time.nowschedule.remaining_occurrences # для завершения расписаний# или предыдущего eventschedule.previous_occurrence(from_time)schedule.previous_occurrences(4, from_time)# или включить предыдущие события с продолжительность перекрывается from_timeschedule.next_occurrences(4, from_time, spans: true)schedule.occurrences_between(from_time, to_time, spans: true)# или задайте продолжительность расписанию и спросите, происходит ли событие_at?schedule = IceCube::Schedule.new(now, продолжительность: 3600)schedule.add_recurrence_rule IceCube::Rule.dailyschedule.occurring_at?(now + 1800) # trueschedule.occurring_between?(t1, t2)# использование end_time также устанавливает расписание продолжительности = IceCube::Schedule.new(start = Time.now, end_time: start + 3600 )schedule.add_recurrence_rule IceCube::Rule.dailyschedule.occurring_at?(start + 3599) # trueschedule.occurring_at?(start + 3600) # false# взять управление на себя и использовать iterationschedule = IceCube::Schedule.newschedule.add_recurrence_rule IceCube::Rule.daily.until( Дата.сегодня + 30)schedule.each_occurrence { |t| ставит т }
Причина, по которой расписания имеют длительность, а не отдельные правила, заключается в обеспечении совместимости с стандартным RFC: http://www.kanzaki.com/docs/ical/rrule.html.
Чтобы ограничить расписания, используйте count
или until
в правилах повторения. Установка end_time
в расписании просто устанавливает продолжительность (от времени начала) для каждого события.
Ice_cube отлично работает без ActiveSupport, но поддерживает только один «локальный» часовой пояс среды ( ENV['TZ']
) или UTC. Чтобы правильно поддерживать несколько часовых поясов (особенно для летнего времени), вам потребуется «active_support/time».
Вхождения расписания будут возвращены в том же классе и часовом поясе, что и start_time расписания. Время начала расписания поддерживается следующим образом:
Time.local (по умолчанию, если время не указано)
Время.utc
ActiveSupport::TimeWithZone (с Time.zone.now
, Time.zone.local
, time.in_time_zone(tz)
)
DateTime (устарело) и Date преобразуются в Time.local.
Ice_cube реализует собственный .to_yaml на основе хеша, поэтому вы можете быстро (и безопасно) сериализовать объекты расписания в хранилище данных и из него.
Он также поддерживает частичную сериализацию в/из ICAL
. Анализ даты и времени с информацией о часовом поясе в настоящее время не поддерживается.
yaml = Schedule.to_yamlIceCube::Schedule.from_yaml(yaml)hash = Schedule.to_hashIceCube::Schedule.from_hash(hash)ical = Schedule.to_icalIceCube::Schedule.from_ical(ical)
Ice_cube может предоставлять материальное или строковое представление отдельных правил или всего расписания.
rule = IceCube::Rule.daily(2).day_of_week(вторник: [1, -1], среда: [2])rule.to_ical # 'FREQ=DAILY;INTERVAL=2;BYDAY=1TU,-1TU,2WE 'rule.to_s # 'Каждые 2 дня в последний и первый вторники и вторую среду'
Существует множество типов правил повторения, которые можно добавить в расписание:
# каждый день.add_recurrence_rule IceCube::Rule.daily# каждый третий день.add_recurrence_rule IceCube::Rule.daily(3)
# каждую неделю.add_recurrence_rule IceCube::Rule.weekly# каждую вторую неделю по понедельникам и вторникам.add_recurrence_rule IceCube::Rule.weekly(2).day(:monday, :tuesday)# для удобного программного расписания (так же, как указано выше). add_recurrence_rule IceCube::Rule.weekly(2).day(1, 2)# указание недельного интервала с другим первым днем недели (по умолчанию воскресенье)schedule.add_recurrence_rule IceCube::Rule.weekly(1, :monday)
# каждый месяц в первый и последний дни месяца.add_recurrence_rule IceCube::Rule.monthly.day_of_month(1, -1)# каждый второй месяц 15-го числа месяца.add_recurrence_rule IceCube::Rule.monthly(2). день_месяца(15)
Правила месяца будут пропускать месяцы, которые слишком коротки для указанного дня месяца (например, отсутствие вхождений в феврале для day_of_month(31)
).
# каждый месяц в первый и последний вторник месяцаchedule.add_recurrence_rule IceCube::Rule.monthly.day_of_week(tuesday: [1, -1])# каждый второй месяц в первый понедельник и последний вторникschedule.add_recurrence_rule IceCube::Rule. ежемесячно(2).day_of_week( понедельник: [1], вторник: [-1])# для удобства программирования (как указано выше)schedule.add_recurrence_rule IceCube::Rule.monthly(2).day_of_week(1 => [1], 2 => [-1])
# каждый год на 100-й день от начала и конца годового графика.add_recurrence_rule IceCube::Rule.yearly.day_of_year(100, -100)# каждый четвертый год в канун нового года.add_recurrence_rule IceCube::Rule.yearly(4) .day_of_year(-1)
# каждый год в тот же день, что и start_time, но в январе и феврале.add_recurrence_rule IceCube::Rule.yearly.month_of_year(:january, :february)# каждый третий год в Marchschedule.add_recurrence_rule IceCube::Rule.yearly(3).month_of_year (:march)# для удобства программирования (то же, что и выше)schedule.add_recurrence_rule IceCube::Rule.yearly(3).month_of_year(3)
# каждый час в ту же минуту и секунду, что и даты начала.add_recurrence_rule IceCube::Rule.hourly# каждый час, в понедельникsschedule.add_recurrence_rule IceCube::Rule.hourly(2).day(:monday)
# каждые 10 минутschedule.add_recurrence_rule IceCube::Rule.minely(10)# каждые полтора часа, в последний вторник месяцаchedule.add_recurrence_rule IceCube::Rule.minely(90).day_of_week(tuesday: [-1])
# каждые секундыchedule.add_recurrence_rule IceCube::Rule. Secondly# каждые 15 секунд с 12:00 до 12:59schedule.add_recurrence_rule IceCube::Rule. Secondly(15).hour_of_day(12)
Команда GetJobber имеет открытый исходный код RecurringSelect, который упрощает работу с IceCube в приложении Rails с помощью некоторых хороших помощников.
Проверьте это на https://github.com/GetJobber/recurring_select.
https://github.com/ice-cube-ruby/ice_cube/graphs/contributors
Используйте трекер проблем GitHub
Вклады приветствуются — я использую GitHub для отслеживания проблем (сопровождающие неудачные тесты — это здорово) и запросов функций.
Отправьте через вилку и запрос на извлечение (включая тесты)
Если вы работаете над чем-то важным, напишите мне заранее