@@ -166,15 +166,15 @@ def each_occurrence(&block)
166166 end
167167
168168 # The next n occurrences after now
169- def next_occurrences ( num , from = nil )
169+ def next_occurrences ( num , from = nil , options = { } )
170170 from = TimeUtil . match_zone ( from , start_time ) || TimeUtil . now ( start_time )
171- enumerate_occurrences ( from + 1 , nil ) . take ( num )
171+ enumerate_occurrences ( from + 1 , nil , options ) . take ( num )
172172 end
173173
174174 # The next occurrence after now (overridable)
175- def next_occurrence ( from = nil )
175+ def next_occurrence ( from = nil , options = { } )
176176 from = TimeUtil . match_zone ( from , start_time ) || TimeUtil . now ( start_time )
177- enumerate_occurrences ( from + 1 , nil ) . next
177+ enumerate_occurrences ( from + 1 , nil , options ) . next
178178 rescue StopIteration
179179 nil
180180 end
@@ -195,26 +195,26 @@ def previous_occurrences(num, from)
195195 end
196196
197197 # The remaining occurrences (same requirements as all_occurrences)
198- def remaining_occurrences ( from = nil )
198+ def remaining_occurrences ( from = nil , options = { } )
199199 require_terminating_rules
200200 from ||= TimeUtil . now ( @start_time )
201- enumerate_occurrences ( from ) . to_a
201+ enumerate_occurrences ( from , nil , options ) . to_a
202202 end
203203
204204 # Returns an enumerator for all remaining occurrences
205- def remaining_occurrences_enumerator ( from = nil )
205+ def remaining_occurrences_enumerator ( from = nil , options = { } )
206206 from ||= TimeUtil . now ( @start_time )
207- enumerate_occurrences ( from )
207+ enumerate_occurrences ( from , nil , options )
208208 end
209209
210210 # Occurrences between two times
211- def occurrences_between ( begin_time , closing_time )
212- enumerate_occurrences ( begin_time , closing_time ) . to_a
211+ def occurrences_between ( begin_time , closing_time , options = { } )
212+ enumerate_occurrences ( begin_time , closing_time , options ) . to_a
213213 end
214214
215215 # Return a boolean indicating if an occurrence falls between two times
216- def occurs_between? ( begin_time , closing_time )
217- enumerate_occurrences ( begin_time , closing_time ) . next
216+ def occurs_between? ( begin_time , closing_time , options = { } )
217+ enumerate_occurrences ( begin_time , closing_time , options ) . next
218218 true
219219 rescue StopIteration
220220 false
@@ -226,9 +226,7 @@ def occurs_between?(begin_time, closing_time)
226226 # occurrences at the end of the range since none of their duration
227227 # intersects the range.
228228 def occurring_between? ( opening_time , closing_time )
229- opening_time = opening_time - duration
230- closing_time = closing_time - 1 if duration > 0
231- occurs_between? ( opening_time , closing_time )
229+ occurs_between? ( opening_time , closing_time , :spans => true )
232230 end
233231
234232 # Return a boolean indicating if an occurrence falls on a certain date
@@ -407,25 +405,30 @@ def reset
407405 # Find all of the occurrences for the schedule between opening_time
408406 # and closing_time
409407 # Iteration is unrolled in pairs to skip duplicate times in end of DST
410- def enumerate_occurrences ( opening_time , closing_time = nil , &block )
408+ def enumerate_occurrences ( opening_time , closing_time = nil , options = { } , &block )
411409 opening_time = TimeUtil . match_zone ( opening_time , start_time )
412410 closing_time = TimeUtil . match_zone ( closing_time , start_time )
413411 opening_time += start_time . subsec - opening_time . subsec rescue 0
414412 opening_time = start_time if opening_time < start_time
413+ spans = options [ :spans ] == true && duration != 0
415414 Enumerator . new do |yielder |
416415 reset
417- t1 = full_required? ? start_time : realign ( opening_time )
416+ t1 = full_required? ? start_time : realign ( ( spans ? opening_time - duration : opening_time ) )
418417 loop do
419418 break unless ( t0 = next_time ( t1 , closing_time ) )
420419 break if closing_time && t0 > closing_time
421- yielder << ( block_given? ? block . call ( t0 ) : t0 ) if t0 >= opening_time
420+ if ( spans ? ( t0 . end_time > opening_time ) : ( t0 >= opening_time ) )
421+ yielder << ( block_given? ? block . call ( t0 ) : t0 )
422+ end
422423 break unless ( t1 = next_time ( t0 + 1 , closing_time ) )
423424 break if closing_time && t1 > closing_time
424425 if TimeUtil . same_clock? ( t0 , t1 ) && recurrence_rules . any? ( &:dst_adjust? )
425426 wind_back_dst
426427 next ( t1 += 1 )
427428 end
428- yielder << ( block_given? ? block . call ( t1 ) : t1 ) if t1 >= opening_time
429+ if ( spans ? ( t1 . end_time > opening_time ) : ( t1 >= opening_time ) )
430+ yielder << ( block_given? ? block . call ( t1 ) : t1 )
431+ end
429432 next ( t1 += 1 )
430433 end
431434 end
0 commit comments