class Mhc::OccurrenceEnumerator
Public Class Methods
new(event, dates, exceptions, recurrence_condition, duration, date_range = nil)
click to toggle source
; The FREQ rule part is REQUIRED, ; but MUST NOT occur more than once.
FREQ = (DAILY|WEEKLY|MONTHLY|YEARLY)
; The UNTIL or COUNT rule parts are OPTIONAL, ; but they MUST NOT occur in the same 'recur'.
UNTIL = (date|date-time) COUNT = d+
; The other rule parts are OPTIONAL, ; but MUST NOT occur more than once.
INTERVAL = d+ # positive value default is 1 BYDAY = ([+-]d{1,2})?(SU|MO|TU|WE|TH|FR|SA),… # 1 to 53 BYMONTHDAY = [+-]d{1,2},… # 1 to 31 BYYEARDAY = [+-]d{1,3},… # 1 to 366 BYWEEKNO = [+-]d{1,3},… # 1 to 53 BYMONTH = d{1,2},… # 1 to 12 BYSETPOS = [+-]d+,… # 1 to 366 WKST = (SU|MO|TU|WE|TH|FR|SA)
# File lib/mhc/occurrence_enumerator.rb, line 27 def initialize(event, dates, exceptions, recurrence_condition, duration, date_range = nil) @event = event # Since some articles with RECURRENCE_CONDITION and without DURATION # makes infinit entries, we have to clip the range by some artificial values # It will make 101 enum entries from 1970-1-1 to now+50 years: # # X-SC-Subject: New Year's Day # X-SC-Cond: Jan 1 # date_range = (Date.new(1970, 1, 1) .. Date.new(Date.today.year + 50)) unless date_range # If we have both DURATION and RANGE, we can take narrower term # by the combination of the both. date_range = duration.narrow(date_range.first, date_range.last) # range.last is effective in narrowing the end_date, # however, we can't adopt range.first to the start_date. # Original start_date derived from DURATION is required for calculating # the start point of recurrence loop in case the # loop interval is larger than one. # # At moment, we will have over-scanning entries even if the range.first # is set narrower than duration.first # # we need some good way to pass the both duration.first and range.first # to the down-stream enumerators. # end_date = date_range.last start_date = duration.first || date_range.first @enumerator = Mhc::DateEnumerator.new(start_date: start_date, end_date: date_range.last) condition_to_enumerator(@enumerator, recurrence_condition, start_date, date_range.last) @enumerator.add_by_range_list(range_list: dates) @exceptions = exceptions.map{|range| range.to_a }.flatten @date_range = date_range end
Public Instance Methods
each() { |occurrence| ... }
click to toggle source
# File lib/mhc/occurrence_enumerator.rb, line 65 def each @enumerator.each do |date_or_range| if date_or_range.respond_to?(:first) first_date = date_or_range.first last_date = date_or_range.last else first_date = date_or_range last_date = date_or_range end if last_date.to_date < @date_range.first or @date_range.last < first_date.to_date next end next if @exceptions.include?(first_date) yield Mhc::Occurrence.new(@event, date_or_range) end end
Private Instance Methods
condition_to_enumerator(enumerator, cond, start_date, end_date)
click to toggle source
# File lib/mhc/occurrence_enumerator.rb, line 84 def condition_to_enumerator(enumerator, cond, start_date, end_date) if cond.yearly? cond.cond_mon.each do |mon| cond.cond_ord.each do |ord| cond.cond_wek.each do |wek| enumerator.add_yearly_by_day(month: mon, nth: ord, wday: wek) end end cond.cond_num.each do |num| enumerator.add_yearly_by_monthday(month: mon, mday: num) end end elsif cond.monthly? cond.cond_ord.each do |ord| cond.cond_wek.each do |wek| enumerator.add_monthly_by_day(nth: ord, wday: wek) end end cond.cond_num.each do |num| enumerator.add_monthly_by_monthday(mday: num) end elsif cond.weekly? cond.cond_wek.each do |wek| enumerator.add_weekly(wday: wek) end end return enumerator end