def each(dountil = nil)
t = @dtstart.clone
if !dountil || t < dountil
yield t
end
count = 1
if !@rrule
return self
end
loop do
days = DaySet.new(t)
hour = nil
min = nil
sec = nil
case @freq
when 'MONTHLY' then days.month = t.month
when 'WEEKLY' then
when 'DAILY' then days.mday = t.month, t.mday
when 'HOURLY' then hour = [t.hour]
when 'MINUTELY' then min = [t.min]
when 'SECONDLY' then sec = [t.sec]
end
bymon = [nil]
if @by['BYMONTH']
bymon = @by['BYMONTH'].split(',')
bymon = bymon.map { |m| m.to_i }
days.intersect_bymon(bymon)
end
if @by['BYYEARDAY']
byyday = @by['BYYEARDAY'].scan(/,?([+-]?[1-9]\d*)/)
dates = byyearday(t.year, byyday)
days.intersect_dates(dates)
end
if @by['BYMONTHDAY']
bymday = @by['BYMONTHDAY'].scan(/,?([+-]?[1-9]\d*)/)
dates = bymonthday(t.year, bymday)
days.intersect_dates(dates)
end
if @by['BYDAY']
byday = @by['BYDAY'].scan(/,?([+-]?[1-9]?\d*)?(SU|MO|TU|WE|TH|FR|SA)/i)
case @freq
when 'YEARLY'
dates = bymon.map { |m| byday_in_monthly(t.year, m, byday) }.flatten
when 'MONTHLY'
dates = byday_in_monthly(t.year, t.month, byday)
when 'WEEKLY'
dates = byday_in_weekly(t.year, t.month, t.mday, @wkst, byday)
when 'DAILY', 'HOURLY', 'MINUTELY', 'SECONDLY'
dates = byday_in_monthly(t.year, t.month, byday)
end
days.intersect_dates(dates)
end
hour = [@dtstart.hour] if !hour
min = [@dtstart.min] if !min
sec = [@dtstart.sec] if !sec
yset = []
days.each do |m,d|
hour.each do |h|
min.each do |n|
sec.each do |s|
y = Time.local(t.year, m, d, h, n, s, 0)
next if y.hour != h
yset << y
end
end
end
end
if @by['BYSETPOS']
bysetpos = @by['BYSETPOS'].split(',')
yset = bysetpos.map do |i|
i = i.to_i
case
when i < 0
yset[i]
when i > 0
yset[i-1]
else
end
end.compact
end
yset.each do |y|
next if y <= @dtstart
count += 1
if(@count && (count > @count))
return self
end
if @until && (y > @until)
return self
end
if dountil && (y >= dountil)
return self
end
yield y
end
begin
case @freq
when 'YEARLY' then
t = t.plus_year(@interval)
when 'MONTHLY' then
t = t.plus_month(@interval)
when 'WEEKLY' then
t = t.plus_day(@interval * 7)
when 'DAILY' then
t = t.plus_day(@interval)
when 'HOURLY' then
t += @interval * 60 * 60
when 'MINUTELY' then
t += @interval * 60
when 'SECONDLY' then
t += @interval
when nil
return self
end
rescue ArgumentError
return self if $!.message =~ /^time out of range$/
raise ArgumentError, "#{$!.message} while adding interval to #{t.inspect}"
end
return self if dountil && (t > dountil)
end
end