tod: Slight inconsistency with overlaps? and exclusive end times

I came across one apparent oddity in an edge case, illustrated by this code:

require 'tod'

all_day = Tod::Shift.new(Tod::TimeOfDay.new(9), Tod::TimeOfDay.new(17), true)


puts "In the middle"
instant = Tod::Shift.new(Tod::TimeOfDay.new(10), Tod::TimeOfDay.new(10), true)
puts all_day.overlaps?(instant)   # true
puts instant.overlaps?(all_day)   # true


puts "At the beginning"
instant = Tod::Shift.new(Tod::TimeOfDay.new(9), Tod::TimeOfDay.new(9), true)
puts all_day.overlaps?(instant)   # true
puts instant.overlaps?(all_day)   # false


puts "At the end"
instant = Tod::Shift.new(Tod::TimeOfDay.new(17), Tod::TimeOfDay.new(17), true)
puts all_day.overlaps?(instant)   # false
puts instant.overlaps?(all_day)   # false

All the calls produce the result which I would expect except the third one. Should that not produce false, if only for consistency?

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Comments: 15 (4 by maintainers)

Most upvoted comments

The ideal implementation for overlaps? in my opinion would be

def overlaps?(other)
  [
    [self, other],
    [self.slide(TimeOfDay::NUM_SECONDS_IN_DAY), other],
    [self, other.slide(TimeOfDay::NUM_SECONDS_IN_DAY)]
  ].any? do |this, that|
    this.range.cover?(that.range.begin) || that.range.cover?(this.range.begin)
  end
end

maybe more explicit is better…

def overlaps?(other)
  range.cover?(other.range.begin) || 
  other.range.cover?(range.begin) ||
  slide(TimeOfDay::NUM_SECONDS_IN_DAY).range.cover?(other.range.begin) || 
  other.range.cover?(slide(TimeOfDay::NUM_SECONDS_IN_DAY).range.begin) ||
  range.cover?(other.slide(TimeOfDay::NUM_SECONDS_IN_DAY).range.begin) || 
  other.slide(TimeOfDay::NUM_SECONDS_IN_DAY).range.cover?(range.begin)
end

Ah - thank you. Yes, that’s a different way of thinking about it and by that reasoning those two do indeed overlap. I’m not sure that way of thinking quite matches the existing implementation though. I will work on it further.

So a Shift which passes through midnight should really be thought of as two Shifts in the same 24 hour period. A shift from 22 to 3 occupies both 22 to 24 and 00 to 03.