class Enumdate::DateEnumerator::Base
Base
class for DateEnumerator
Public Class Methods
new(first_date:, interval: 1, wkst: 1)
click to toggle source
# File lib/enumdate/date_enumerator.rb, line 10 def initialize(first_date:, interval: 1, wkst: 1) @first_date, @interval, @wkst = first_date, interval, wkst @frame_manager = frame_manager.new(first_date, interval, wkst) @duration_begin = first_date @duration_until = nil end
Public Instance Methods
each() { |first_date| ... }
click to toggle source
rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
# File lib/enumdate/date_enumerator.rb, line 18 def each return enum_for(:each) unless block_given? # ~first_date~ value always counts as the first occurrence # even if it does not match the specified rule. # cf. DTSTART vs RRULE in RFC5445. yield @first_date if between_duration?(@first_date) @frame_manager.each do |frame| # Avoid inifinit loops even if the rule emits no occurrences # such as "31st April in every year". # (Every ~occurrence_in_frame(frame)~ returns nil) break if @duration_until && @duration_until < frame # In some cases, ~occurrence_in_frame~ returns nil. # For example, a recurrence that returns 31st of each month # will return nil for short months such as April and June. next unless (date = occurrence_in_frame(frame)) break if @duration_until && @duration_until < date # ~occurrence_in_frame~ may return a date earlier than # ~first_date~ in the first iteration. This is because # ~first_date~ does not necessarily follow the repetetion # rule. For example, if the rule is "every August 1st" and # ~first_date~ is August 15th, The first occurrence calculated # by the rule returns "August 1st", which is earlier than # August 15th. In this context, ~@duration_begin~ is the matter. next if date < @duration_begin # Ignore ~first_date~ not to yield twice. next if date == @first_date yield date end end
forward_to(date)
click to toggle source
Set the new beginning of duration for the recurrence rule.
It also controls the underlying frame manager. Since the frame manager is enough smart to avoid unnecessary repetition, there is no problem in setting the date hundred years later.
Note that the meaning of calling ~forward_to~ is different from that of setting the ~first_date~ parameter on creation. For example, if a yearly event has two-years ~interval~:
1) if first_date is 2021-08-01 and forward_to
2022-08-01,
it will create [2021-08-01 2023-08-01 ...]
2) if first_date is 2022-08-01,
it will create [2022-08-01 2024-08-01 ...]
# File lib/enumdate/date_enumerator.rb, line 72 def forward_to(date) @frame_manager.forward_to(date) @duration_begin = date self end
rewind()
click to toggle source
Imprement rewind for Enumrator class
# File lib/enumdate/date_enumerator.rb, line 79 def rewind @frame_manager.rewind self end
until(date)
click to toggle source
Set the new end of duration for the recurrence rule.
# File lib/enumdate/date_enumerator.rb, line 85 def until(date) @duration_until = date self end
Private Instance Methods
between_duration?(date)
click to toggle source
# File lib/enumdate/date_enumerator.rb, line 92 def between_duration?(date) (!@duration_begin || @duration_begin <= date) && (!@duration_until || date <= @duration_until) end
frame_manager()
click to toggle source
# File lib/enumdate/date_enumerator.rb, line 97 def frame_manager raise NotImplementedError end
occurrence_in_frame(date)
click to toggle source
# File lib/enumdate/date_enumerator.rb, line 101 def occurrence_in_frame(date) raise NotImplementedError end