Class: Tod::Shift
- Inherits:
-
Object
- Object
- Tod::Shift
- Defined in:
- lib/tod/shift.rb
Overview
Shift is a range-like class that handles wrapping around midnight. For example, the Shift of 2300 to 0200 would include 0100.
Instance Attribute Summary collapse
-
#beginning ⇒ Object
readonly
Returns the value of attribute beginning.
-
#ending ⇒ Object
readonly
Returns the value of attribute ending.
-
#range ⇒ Object
readonly
Returns the value of attribute range.
Instance Method Summary collapse
- #==(other) ⇒ Object
- #contains?(shift) ⇒ Boolean
-
#duration ⇒ Object
Return shift duration in seconds.
- #eql?(other) ⇒ Boolean
- #exclude_end? ⇒ Boolean
- #hash ⇒ Object
-
#include?(tod) ⇒ Boolean
Returns true if the time of day is inside the shift, false otherwise.
-
#initialize(beginning, ending, exclude_end = false) ⇒ Shift
constructor
A new instance of Shift.
-
#overlaps?(other) ⇒ Boolean
Returns true if ranges overlap, false otherwise.
-
#slide(seconds) ⇒ Object
Move start and end by a number of seconds and return new shift.
Constructor Details
#initialize(beginning, ending, exclude_end = false) ⇒ Shift
Returns a new instance of Shift.
8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
# 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 |
Instance Attribute Details
#beginning ⇒ Object (readonly)
Returns the value of attribute beginning.
6 7 8 |
# File 'lib/tod/shift.rb', line 6 def beginning @beginning end |
#ending ⇒ Object (readonly)
Returns the value of attribute ending.
6 7 8 |
# File 'lib/tod/shift.rb', line 6 def ending @ending end |
#range ⇒ Object (readonly)
Returns the value of attribute range.
6 7 8 |
# File 'lib/tod/shift.rb', line 6 def range @range end |
Instance Method Details
#==(other) ⇒ Object
66 67 68 |
# File 'lib/tod/shift.rb', line 66 def ==(other) @range == other.range end |
#contains?(shift) ⇒ Boolean
52 53 54 |
# File 'lib/tod/shift.rb', line 52 def contains?(shift) self.include?(shift.beginning) && self.include?(shift.ending) end |
#duration ⇒ Object
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
58 59 60 |
# File 'lib/tod/shift.rb', line 58 def duration @range.last - @range.first end |
#eql?(other) ⇒ Boolean
70 71 72 |
# File 'lib/tod/shift.rb', line 70 def eql?(other) @range.eql?(other.range) end |
#exclude_end? ⇒ Boolean
62 63 64 |
# File 'lib/tod/shift.rb', line 62 def exclude_end? @exclude_end end |
#hash ⇒ Object
74 75 76 |
# File 'lib/tod/shift.rb', line 74 def hash @range.hash end |
#include?(tod) ⇒ Boolean
Returns true if the time of day is inside the shift, false otherwise.
28 29 30 31 32 |
# 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) ⇒ Boolean
Returns true if ranges overlap, false otherwise.
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'lib/tod/shift.rb', line 35 def overlaps?(other) max_seconds = TimeOfDay::NUM_SECONDS_IN_DAY # Standard case, when Shifts are on the same day a, b = [self, other].map(&:range).sort_by(&:first) op = a.exclude_end? ? :> : :>= return true if a.last.send(op, b.first) # Special cases, when Shifts span to the next day return false if (a.last < max_seconds) && (b.last < max_seconds) a = Range.new(a.first, a.last - max_seconds, a.exclude_end?) if a.last > max_seconds b = Range.new(b.first, b.last - max_seconds, b.exclude_end?) if b.last > max_seconds a, b = [a, b].sort_by(&:last) b.last.send(op, a.last) && a.last.send(op, b.first) end |
#slide(seconds) ⇒ Object
Move start and end by a number of seconds and return new shift.
79 80 81 |
# File 'lib/tod/shift.rb', line 79 def (seconds) self.class.new(beginning + seconds, ending + seconds, exclude_end?) end |