gem instalar ice_cube
ice_cube é uma biblioteca Ruby para lidar facilmente com eventos repetidos (programações). A API é modelada a partir de eventos iCalendar, em uma agradável sintaxe Ruby. O poder está na capacidade de especificar várias regras e fazer com que o ice_cube descubra rapidamente se a programação cai em uma determinada data (.occurs_on?) ou em que horários ela ocorre (.occurrences, .first, .all_occurrences).
Imagine que você quer:
Toda sexta-feira, dia 13, que cai em outubro
Você escreveria:
agendar = IceCube::Schedule.newschedule.add_recurrence_rule( IceCube::Rule.yearly.day_of_month(13).day(:sexta-feira).mês_do_ano(:outubro))
Apresentação da Lone Star Ruby Conf (slides, YouTube)
Introdução rápida
Site de documentação
Com ice_cube, você pode especificar (em ordem crescente de precedência):
Regras de Recorrência - Regras sobre como incluir horários recorrentes em uma programação
Tempos de recorrência - Para incluir especificamente em um cronograma
Tempos de exceção - Para excluir especificamente de uma programação
Exemplo: Especificando uma recorrência com um horário de exceção. Requer "rails/activesupport" ( gem install 'activesupport'
).
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# lista ocorrências até end_time (end_time é necessário para regras de não encerramento)occurrences = schedule.occurrences(end_time) # [now]# ou todas as ocorrências (somente para agendamentos de encerramento) ocorrências = agenda.all_occurrences # [agora, agora + 2.dias, agora + 3.dias]# ou marque apenas um timeschedule.occurs_at?(now + 1.day) # falseschedule.occurs_at?(now + 2.days) # true# ou verifique apenas um único dayschedule.occurs_on?(Date.today) # true# ou verifique se ocorre entre dois dateschedule.occurs_between?(agora, agora + 30.dias) # trueschedule.occurs_between?(agora + 4.dias, agora + 30.dias) # false# ou as primeiras (n) ocorrênciasschedule.first(2) # [agora, agora + 2.dias]schedule.first # agora# ou as últimas (n) ocorrências (se a programação termina)schedule.last(2) # [agora + 2.dias, agora + 3.dias]schedule.last # agora + 3.dias# ou no próximo ocorrênciaschedule.next_occurrence(from_time) # o padrão é Time.nowschedule.next_occurrences(4, from_time) # o padrão é Time.nowschedule.remaining_occurrences # para encerrar agendamentos# ou as ocorrências anterioreschedule.previous_occurrence(from_time)schedule.previous_occurrences(4, from_time)# ou incluir ocorrências anteriores com duração sobrepondo from_timeschedule.next_occurrences(4, from_time, spans: true)schedule.occurrences_between(from_time, to_time, spans: true)# ou atribua uma duração ao agendamento e pergunte se ocorre_at?schedule = IceCube::Schedule.new(now, duração: 3600)schedule.add_recurrence_rule IceCube::Rule.dailyschedule.occurring_at?(now + 1800) # trueschedule.occurring_between?(t1, t2)# usar end_time também define as duraçõeschedule = 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# assuma o controle e use iterationschedule = IceCube::Schedule.newschedule.add_recurrence_rule IceCube::Rule.daily.until( Data.hoje + 30)schedule.each_occurrence { |t| coloca t}
A razão pela qual os cronogramas têm durações e não regras individuais é para manter a compatibilidade com o RFC ical: http://www.kanzaki.com/docs/ical/rrule.html
Para limitar programações use count
ou until
nas regras de recorrência. Definir end_time
na programação apenas define a duração (a partir do horário de início) de cada ocorrência.
ice_cube funciona muito bem sem ActiveSupport, mas suporta apenas o fuso horário "local" único do ambiente ( ENV['TZ']
) ou UTC. Para oferecer suporte correto a vários fusos horários (especialmente para horário de verão), você deve exigir 'active_support/time'.
As ocorrências de um agendamento serão retornadas na mesma classe e fuso horário do start_time do agendamento. Os horários de início da programação são suportados como:
Time.local (padrão quando nenhum horário é especificado)
Hora.utc
ActiveSupport::TimeWithZone (com Time.zone.now
, Time.zone.local
, time.in_time_zone(tz)
)
DateTime (obsoleto) e Date são convertidos em Time.local
ice_cube implementa seu próprio .to_yaml baseado em hash, para que você possa serializar objetos de agendamento de forma rápida (e segura) dentro e fora de seu armazenamento de dados
Ele também suporta serialização parcial de/para ICAL
. A análise de data e hora com informações de fuso horário não é suportada atualmente.
yaml = agenda.to_yamlIceCube::Schedule.from_yaml(yaml)hash = agenda.to_hashIceCube::Schedule.from_hash(hash)ical = agenda.to_icalIceCube::Schedule.from_ical(ical)
ice_cube pode fornecer representações ical ou string de regras individuais ou de todo o cronograma.
regra = IceCube::Rule.daily(2).day_of_week(terça-feira: [1, -1], quarta-feira: [2])rule.to_ical # 'FREQ=DAILY;INTERVAL=2;BYDAY=1TU,-1TU,2WE 'rule.to_s # 'A cada 2 dias na última e na 1ª terça-feira e na 2ª quarta-feira'
Existem muitos tipos de regras de recorrência que podem ser adicionadas a uma programação:
# todos os diaschedule.add_recurrence_rule IceCube::Rule.daily# todos os terceiros diaschedule.add_recurrence_rule IceCube::Rule.daily(3)
# every weekchedule.add_recurrence_rule IceCube::Rule.weekly# semana sim, semana não na segunda e terça-feiraschedule.add_recurrence_rule IceCube::Rule.weekly(2).day(:monday, :tuesday)# para programação de conveniência programática (igual ao acima). add_recurrence_rule IceCube::Rule.weekly(2).day(1, 2)# especificando um intervalo semanal com um primeiro dia da semana diferente (o padrão é domingo)schedule.add_recurrence_rule IceCube::Rule.weekly(1, :monday)
# todos os meses no primeiro e no último dia do mês agendado.add_recurrence_rule IceCube::Rule.monthly.day_of_month(1, -1)# a cada dois meses no dia 15 do mês programado.add_recurrence_rule IceCube::Rule.monthly(2). dia_do_mês(15)
As regras mensais irão ignorar os meses que são muito curtos para o dia do mês especificado (por exemplo, nenhuma ocorrência em fevereiro para day_of_month(31)
).
# todos os meses, na primeira e na última terça-feira do mês agendado.add_recurrence_rule IceCube::Rule.monthly.day_of_week(terça-feira: [1, -1])# a cada dois meses, na primeira segunda-feira e na última terça-feira.add_recurrence_rule IceCube::Rule. mensal(2).dia_da_semana( segunda-feira: [1], terça-feira: [-1])# para conveniência programática (igual ao acima)schedule.add_recurrence_rule IceCube::Rule.monthly(2).day_of_week(1 => [1], 2 => [-1])
# todos os anos nos 100 dias a partir do início e do final do ano programado.add_recurrence_rule IceCube::Rule.yearly.day_of_year(100, -100)# a cada quatro anos na véspera de ano novo.add_recurrence_rule IceCube::Rule.yearly(4) .dia_do_ano(-1)
# todos os anos no mesmo dia que start_time, mas em janeiro e fevereiroschedule.add_recurrence_rule IceCube::Rule.yearly.month_of_year(:january, :february)# a cada três anos em marchschedule.add_recurrence_rule IceCube::Rule.yearly(3).month_of_year (:março)# para conveniência programática (o mesmo que acima)schedule.add_recurrence_rule IceCube::Rule.yearly(3).month_of_year(3)
# a cada hora no mesmo minuto e segundo do início de dataschedule.add_recurrence_rule IceCube::Rule.hourly# a cada duas horas, em mondaysschedule.add_recurrence_rule IceCube::Rule.hourly(2).day(:monday)
# a cada 10 minutosschedule.add_recurrence_rule IceCube::Rule. Minutely(10)# a cada hora e meia, na última terça-feira do mêschedule.add_recurrence_rule IceCube::Rule. Minutely(90).day_of_week(tuesday: [-1])
# a cada segundoschedule.add_recurrence_rule IceCube::Rule.secondly# a cada 15 segundos entre 12h00 e 12h59schedule.add_recurrence_rule IceCube::Rule.secondly(15).hour_of_day(12)
A equipe do GetJobber possui o RecurringSelect de código aberto, o que torna mais fácil trabalhar com o IceCube em um aplicativo Rails por meio de alguns ajudantes interessantes.
Confira em https://github.com/GetJobber/recurring_select
https://github.com/ice-cube-ruby/ice_cube/graphs/contributors
Use o rastreador de problemas do GitHub
Contribuições são bem-vindas - eu uso o GitHub para rastreamento de problemas (testes com falha são fantásticos) e solicitações de recursos
Enviar via fork e pull request (incluir testes)
Se você estiver trabalhando em algo importante, envie-me uma mensagem com antecedência