Class: Timerage::TimeInterval

Inherits:
Range
  • Object
show all
Defined in:
lib/timerage/time_interval.rb

Overview

A range of time. The exposes the Range like interface.

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.from_range(range) ⇒ Object

Returns a new TimeInterval based on the specified range



34
35
36
# File 'lib/timerage/time_interval.rb', line 34

def from_range(range)
  new(range.begin, range.end, range.exclude_end?)
end

.from_time_and_duration(time, duration, exclude_end: true) ⇒ Object

Returns a new TimeInterval

time - the beginning or end of the interval duration - the duration of the interval, if negative the

interval will start before`time`

exclude_end - whether the end time is excluded from the interval



25
26
27
28
29
30
31
# File 'lib/timerage/time_interval.rb', line 25

def from_time_and_duration(time, duration, exclude_end: true)
  if duration >= 0
    new(time, time + duration, exclude_end)
  else
    new(time + duration, time, exclude_end)
  end
end

.new(*args) ⇒ Object

Returns a new TimeInterval

start_time - the beginning of the interval end_time - the end of the interval exclude_end - whether the end time is excluded from the interval



13
14
15
16
17
# File 'lib/timerage/time_interval.rb', line 13

def new(*args)
  return from_range(*args) if args.first.respond_to?(:exclude_end?)

  super
end

Instance Method Details

#&(other) ⇒ Object

Returns a new TimeInterval that is the intersection of ‘self` and `other`.



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/timerage/time_interval.rb', line 136

def &(other)
  fail ArgumentError, "#{other} does not overlap #{self}" unless self.overlap? other

  new_begin = [self.begin, other.begin].max
  new_end,ex_end = if self.end > other.end
                     [other.end, other.exclude_end?]
                   elsif self.end < other.end
                     [self.end, self.exclude_end?]
                   elsif self.exclude_end? || other.exclude_end?
                     [self.end, true]
                   else
                     [self.end, false]
                   end

  self.class.new(new_begin, new_end, ex_end)
end

#+(other) ⇒ Object

Return new TimeInterval that is the concatenation of self and other (if possible).

Raises ArgumentError if other is not adjacent to self chronologically.



71
72
73
74
75
# File 'lib/timerage/time_interval.rb', line 71

def +(other)
  fail ArgumentError, "other must be adjacent to self" unless adjacent_to?(other)

  self.class.new([self.begin, other.begin].min, [self.end, other.end].max)
end

#<=>(other) ⇒ Object



120
121
122
123
124
# File 'lib/timerage/time_interval.rb', line 120

def <=>(other)
  return super unless rangeish?(other)

  self.begin <=> other.begin
end

#==(other) ⇒ Object



126
127
128
129
130
131
132
133
# File 'lib/timerage/time_interval.rb', line 126

def ==(other)
  self.begin == other.begin &&
    self.end == other.end &&
    self.exclude_end? == other.exclude_end?

rescue NoMethodError
  false
end

#adjacent_to?(other) ⇒ Boolean

Returns:

  • (Boolean)


88
89
90
# File 'lib/timerage/time_interval.rb', line 88

def adjacent_to?(other)
  other.begin == self.end || other.end == self.begin
end

#cover?(time_or_interval) ⇒ Boolean

Returns:

  • (Boolean)


92
93
94
95
96
97
98
99
100
101
102
103
104
# File 'lib/timerage/time_interval.rb', line 92

def cover?(time_or_interval)
  other = time_or_interval
  return super unless rangeish?(other)
  return false unless overlap?(other)

  self_end, other_end = self.end, other.end
  other.begin >= self.begin &&
    if !self.exclude_end? || other.exclude_end?
      other_end <= self_end
    else
      other_end < self_end
    end
end

#durationObject

Returns number of seconds in this interval



46
47
48
# File 'lib/timerage/time_interval.rb', line 46

def duration
  self.end - self.begin
end

#getutcObject



83
84
85
86
# File 'lib/timerage/time_interval.rb', line 83

def getutc
  return self if self.begin.utc? && self.end.utc?
  self.class.new(self.begin.getutc, self.end.getutc, self.exclude_end?)
end

#iso8601(*args) ⇒ Object

Returns an ISO8601 interval representation of self Takes same args as Time#iso8601



79
80
81
# File 'lib/timerage/time_interval.rb', line 79

def iso8601(*args)
  "#{self.begin.iso8601(*args)}/#{self.end.iso8601(*args)}"
end

#overlap?(other) ⇒ Boolean

Returns:

  • (Boolean)


106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/timerage/time_interval.rb', line 106

def overlap?(other)
  if self.begin <= other.begin
    earliest, latest = self, other
  else
    earliest, latest = other, self
  end

  latest_begin, earliest_end = latest.begin, earliest.end
  return true  if latest_begin < earliest_end
  return false if earliest_end < latest_begin

  !earliest.exclude_end?
end

#slice(duration) ⇒ Object



58
59
60
61
62
63
64
# File 'lib/timerage/time_interval.rb', line 58

def slice(duration)
  time_enumerator(duration)
    .each_cons(2).map { |s_begin, s_end| TimeInterval.new(s_begin, s_end, exclusive_end_slice?(s_end)) }
    .then do |slices|
      slices << TimeInterval.new(slices.last.end, self.end, exclusive_end_slice?(slices.last.end + duration)) if slices.present?
    end
end

#step(n, &blk) ⇒ Object



50
51
52
53
54
55
56
# File 'lib/timerage/time_interval.rb', line 50

def step(n, &blk)
  if block_given?
    time_enumerator(n).each(&blk)
  else
    time_enumerator(n)
  end
end

#to_time_intervalObject



39
40
41
# File 'lib/timerage/time_interval.rb', line 39

def to_time_interval
  self
end