class Tod::Shift
Shift
is a range-like class that handles wrapping around midnight. For example, the Shift
of 2300 to 0200 would include 0100.
Attributes
beginning[R]
ending[R]
range[R]
Public Class Methods
new(beginning, ending, exclude_end=false)
click to toggle source
# File lib/tod/shift.rb, line 8 def initialize(beginning, ending, exclude_end=false) raise ArgumentError, "beginning can not be nil" unless beginning raise ArgumentError, "ending can not be nil" unless ending unless [true, false].include? exclude_end raise ArgumentError, "exclude_end must be true or false" end @beginning = beginning @ending = ending @exclude_end = exclude_end normalized_ending = ending.to_i normalized_ending += TimeOfDay::NUM_SECONDS_IN_DAY if normalized_ending < beginning.to_i @range = Range.new(beginning.to_i, normalized_ending, @exclude_end) freeze # Shift instances are value objects end
Public Instance Methods
==(other)
click to toggle source
# File lib/tod/shift.rb, line 86 def ==(other) @range == other.range end
contains?(shift)
click to toggle source
# File lib/tod/shift.rb, line 72 def contains?(shift) self.include?(shift.beginning) && self.include?(shift.ending) end
duration()
click to toggle source
Return shift duration in seconds. if ending is lower than beginning this method will calculate the duration as the ending time is from the following day
# File lib/tod/shift.rb, line 78 def duration @range.last - @range.first end
eql?(other)
click to toggle source
# File lib/tod/shift.rb, line 90 def eql?(other) @range.eql?(other.range) end
exclude_end?()
click to toggle source
# File lib/tod/shift.rb, line 82 def exclude_end? @exclude_end end
hash()
click to toggle source
# File lib/tod/shift.rb, line 94 def hash @range.hash end
include?(tod)
click to toggle source
Returns true if the time of day is inside the shift, false otherwise.
# File lib/tod/shift.rb, line 28 def include?(tod) second = tod.to_i second += TimeOfDay::NUM_SECONDS_IN_DAY if second < @range.first @range.cover?(second) end
overlaps?(other)
click to toggle source
Returns true if ranges overlap, false otherwise.
# File lib/tod/shift.rb, line 35 def overlaps?(other) a, b = [self, other].map(&:range) # # Although a Shift which passes through midnight is stored # internally as lasting more than TimeOfDay::NUM_SECONDS_IN_DAY # seconds from midnight, that's not how it is meant to be # handled. Rather, it consists of two chunks: # # range.first => Midnight # Midnight => range.last # # The second one is *before* the first. None of it is more than # TimeOfDay::NUM_SECONDS_IN_DAY after midnight. We thus need to shift # each of our ranges to cover all overlapping possibilities. # one_day = TimeOfDay::NUM_SECONDS_IN_DAY ashifted = Range.new(a.first + one_day, a.last + one_day, a.exclude_end?) bshifted = Range.new(b.first + one_day, b.last + one_day, b.exclude_end?) # # For exclusive ranges we need: # # a.ending > b.beginning && b.ending > a.beginning # # and for inclusive we need: # # a.ending >= b.beginning && b.ending >= a.beginning # aop = a.exclude_end? ? :> : :>= bop = b.exclude_end? ? :> : :>= # (a.last.send(aop, b.first) && b.last.send(bop, a.first)) || (ashifted.last.send(aop, b.first) && b.last.send(bop, ashifted.first)) || (a.last.send(aop, bshifted.first) && bshifted.last.send(bop, a.first)) end
slide(seconds)
click to toggle source
Move start and end by a number of seconds and return new shift.
# File lib/tod/shift.rb, line 99 def slide(seconds) self.class.new(beginning + seconds, ending + seconds, exclude_end?) end