Class: TimeSlot

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/slotter/time_slot.rb

Overview

A TimeSlot object holds the start date and finish date of a period in time

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(start, finish) ⇒ TimeSlot

Returns a new instance of TimeSlot.



6
7
8
9
# File 'lib/slotter/time_slot.rb', line 6

def initialize(start, finish)
  @start = start
  @finish = finish
end

Instance Attribute Details

#finishObject (readonly)

Returns the value of attribute finish.



4
5
6
# File 'lib/slotter/time_slot.rb', line 4

def finish
  @finish
end

#startObject (readonly)

Returns the value of attribute start.



4
5
6
# File 'lib/slotter/time_slot.rb', line 4

def start
  @start
end

Instance Method Details

#+(other_slot) ⇒ Object

Concatenation—Returns a set of new TimeSlot(s) that are the result of concatenating the other_slot to this slot. Returns nil if the slots are disjoint.



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
# File 'lib/slotter/time_slot.rb', line 94

def +(other_slot)
  return self unless other_slot
  # Case 1
  if self.start == other_slot.start and self.finish == other_slot.finish
    return self.clone
  end
  # Case 2 or Case 3
  if (self.start == other_slot.start and self.finish < other_slot.finish) or
     (self.start > other_slot.start and self.finish < other_slot.finish)
    return other_slot.clone
  end
  # Case 4
  if self.finish == other_slot.start
    return TimeSlot.new(self.start, other_slot.finish)
  end
  # Case 5
  if self.start == other_slot.finish
    return TimeSlot.new(other_slot.start, self.finish)
  end
  # Case 6 or Case 7 (Disjoint)
  if (self.finish < other_slot.start) or
     (self.start > other_slot.finish)
     return nil
  end
  # Case 8, Case 9 or Case 10
  if (self.start == other_slot.start and self.finish > other_slot.finish) or
     (self.start < other_slot.start and self.finish == other_slot.finish) or
     (self.start < other_slot.start and self.finish > other_slot.finish)
    return self.clone
  end
  # Case 11
  if self.start < other_slot.start and self.finish < other_slot.finish and self.finish > other_slot.start
    return TimeSlot.new(self.start, other_slot.finish)
  end
  # Case 12
  if self.start > other_slot.start and self.finish > other_slot.finish and self.start < other_slot.finish
    return TimeSlot.new(other_slot.start, self.finish)
  end
end

#-(other_slot) ⇒ Object

Subtraction—Returns a set of new TimeSlot(s) that are the result of removing the other_slot from this slot.



56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/slotter/time_slot.rb', line 56

def -(other_slot)
  return self unless other_slot
  # Case 1, Case 2 or Case 3
  if (self.start == other_slot.start and self.finish == other_slot.finish) or
     (self.start == other_slot.start and self.finish < other_slot.finish) or
     (self.start > other_slot.start and self.finish < other_slot.finish)
    return []
  end
  # Case 4, Case 5, Case 6 or Case 7
  if (self.finish == other_slot.start) or
     (self.start == other_slot.finish) or
     (self.finish < other_slot.start) or
     (self.start > other_slot.finish)
    return [self.clone]
  end
  # Case 8
  if self.start == other_slot.start and self.finish > other_slot.finish
    return [TimeSlot.new(other_slot.finish, self.finish)]
  end
  # Case 9 or Case 11
  if (self.start < other_slot.start and self.finish == other_slot.finish) or
     (self.start < other_slot.start and self.finish < other_slot.finish and self.finish > other_slot.start)
    return [TimeSlot.new(self.start, other_slot.start)]
  end
  # Case 10
  if self.start < other_slot.start and self.finish > other_slot.finish
    return [TimeSlot.new(self.start, other_slot.start),
            TimeSlot.new(other_slot.finish, self.finish)]
  end
  # Case 12
  if self.start > other_slot.start and self.finish > other_slot.finish and self.start < other_slot.finish
    return [TimeSlot.new(other_slot.finish, self.finish)]
  end
end

#<=>(other_slot) ⇒ Object

Comparison—Returns an integer (-1, 0, or +1) if this time slot is less than, equal to, or greater than other_slot. First we compare the start of both slots and if they are equal then we compare the finish of both slots. Thus, two arrays are “equal” according to TimeSlot#<=> if an only if they have the same start and finish.

today_at_nine = Chronic.parse("today 09:00")
today_at_ten = Chronic.parse("today 10:00")
today_at_eleven = Chronic.parse("today 11:00")

a = TimeSlot.new(today_at_nine, today_at_ten)
b = TimeSlot.new(today_at_ten, today_at_eleven)
c = TimeSlot.new(today_at_nine, today_at_eleven)

a <=> b   #=> -1
a <=> c   #=> -1
b <=> c   #=> +1


158
159
160
161
# File 'lib/slotter/time_slot.rb', line 158

def <=>(other_slot)
  cmp = self.start <=> other_slot.start
  (cmp == 0) ? self.finish <=> other_slot.finish : cmp
end

#==(other_slot) ⇒ Object

Equality—Two time slots are equal if they have the same start and finish



135
136
137
# File 'lib/slotter/time_slot.rb', line 135

def ==(other_slot)
  (self.start == other_slot.start and self.finish == other_slot.finish)
end

#contains?(other_slot) ⇒ Boolean

Returns true if this TimeSlot contains the other_slot otherwise false.

Returns:

  • (Boolean)


31
32
33
34
# File 'lib/slotter/time_slot.rb', line 31

def contains?(other_slot)
  (self.contains_start_of?(other_slot) and 
  self.contains_finish_of?(other_slot))
end

#contains_finish_of?(other_slot) ⇒ Boolean

Returns true if this TimeSlot contains the finish of other_slot otherwise false.

Returns:

  • (Boolean)


50
51
52
# File 'lib/slotter/time_slot.rb', line 50

def contains_finish_of?(other_slot)
  (self.start < other_slot.finish and self.finish > other_slot.finish)
end

#contains_start_of?(other_slot) ⇒ Boolean

Returns true if this TimeSlot contains the start of other_slot otherwise false.

Returns:

  • (Boolean)


44
45
46
# File 'lib/slotter/time_slot.rb', line 44

def contains_start_of?(other_slot)
  (self.start < other_slot.start and self.finish > other_slot.start)
end

#disjoint?(other_slot) ⇒ Boolean

Returns true if this TimeSlot does not intersect with other_slot otherwise false.

Returns:

  • (Boolean)


24
25
26
27
# File 'lib/slotter/time_slot.rb', line 24

def disjoint?(other_slot)
  (self.start > other_slot.finish) or 
  (self.finish < other_slot.start)
end

#durationObject

Returns the difference between start and finish of the TimeSlot in seconds



12
13
14
# File 'lib/slotter/time_slot.rb', line 12

def duration
  (self.finish - self.start)
end

#intersects_with?(other_slot) ⇒ Boolean

Returns true if this TimeSlot intersects with other_slot otherwise false.

Returns:

  • (Boolean)


18
19
20
# File 'lib/slotter/time_slot.rb', line 18

def intersects_with?(other_slot)
  !disjoint?(other_slot)
end

#split(length) ⇒ Object

Split this time slot into a set of new TimeSlot(s) where the duration of

each slot is equal to or smaller than length.

The duration of the last slot in the result will be set to the remainder if the this time slot cannot be divided equally based on length.

a = TimeSlot.new(Chronic.parse("today 10:00"), Chronic.parse("today 12:30"))

a.split(3600) #=> [
    #<TimeSlot:0x1018cf3a0 @start=Sun Nov 01 10:00:00 +0000 2009, 
      @finish=Sun Nov 01 11:00:00 +0000 2009>, 
    #<TimeSlot:0x1018cf260 @start=Sun Nov 01 11:00:00 +0000 2009, 
      @finish=Sun Nov 01 12:00:00 +0000 2009>, 
    #<TimeSlot:0x1018cf198 @start=Sun Nov 01 12:00:00 +0000 2009, 
      @finish=Sun Nov 01 12:30:00 +0000 2009>]


179
180
181
182
183
184
185
186
187
188
189
# File 'lib/slotter/time_slot.rb', line 179

def split(length)
  result = []
  if self.duration <= length
    result << self.clone
  else
    current = TimeSlot.new(self.start, self.start + length)
    result << current
    result += (self - current)[0].split(length)
  end
  return result
end

#to_sObject

Shows the start and end of this TimeSlot



192
193
194
# File 'lib/slotter/time_slot.rb', line 192

def to_s
  "#{self.start} to #{self.finish}"
end

#within?(other_slot) ⇒ Boolean

Returns true if this TimeSlot is within the other_slot otherwise false.

Returns:

  • (Boolean)


38
39
40
# File 'lib/slotter/time_slot.rb', line 38

def within?(other_slot)
  other_slot.contains?(self)
end