class Timerage::TimeInterval

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

Public Class Methods

new(*args) click to toggle source
# File lib/timerage/time_interval.rb, line 8
def new(*args)
  args = [args.first.begin, args.first.end, args.first.exclude_end?] if args.first.respond_to?(:exclude_end?)
  new_obj = allocate
  new_obj.send(:initialize, *args)
  new_obj
end

Protected Class Methods

iso8601(str, exclusive_end: true) click to toggle source

Returns a new TimeInterval representation of the iso8601 interval represented by the specified string.

Currently this only supports `<begin>/<end>` style time intervals.

# File lib/timerage/time_interval.rb, line 157
def self.iso8601(str, exclusive_end: true)
  new *str.split("/", 2).map{|s| Time.iso8601(s)}, exclusive_end

rescue ArgumentError
  raise ArgumentError, "Invalid iso8601 interval: #{str.inspect}"
end

Public Instance Methods

&(other) click to toggle source

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

# File lib/timerage/time_interval.rb, line 113
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) click to toggle source

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

Raises ArgumentError if other is not adjacent to self chronologically.

# File lib/timerage/time_interval.rb, line 48
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) click to toggle source
Calls superclass method
# File lib/timerage/time_interval.rb, line 97
def <=>(other)
  return super unless rangeish?(other)

  self.begin <=> other.begin
end
==(other) click to toggle source
# File lib/timerage/time_interval.rb, line 103
def ==(other)
  self.begin == other.begin &&
    self.end == other.end &&
    self.exclude_end? == other.exclude_end?

rescue NoMethodError
  false
end
adjacent_to?(other) click to toggle source
# File lib/timerage/time_interval.rb, line 65
def adjacent_to?(other)
  other.begin == self.end || other.end == self.begin
end
cover?(time_or_interval) click to toggle source
Calls superclass method
# File lib/timerage/time_interval.rb, line 69
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
duration() click to toggle source

Returns number of seconds in this interval

# File lib/timerage/time_interval.rb, line 23
def duration
  self.end - self.begin
end
getutc() click to toggle source
# File lib/timerage/time_interval.rb, line 60
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) click to toggle source

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

# File lib/timerage/time_interval.rb, line 56
def iso8601(*args)
  "#{self.begin.iso8601(*args)}/#{self.end.iso8601(*args)}"
end
overlap?(other) click to toggle source
# File lib/timerage/time_interval.rb, line 83
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(seconds) click to toggle source
# File lib/timerage/time_interval.rb, line 35
def slice(seconds)
  time_enumerator(seconds)
    .map{|t|
      end_time = [t+seconds, self.end].min
      inclusive = (t == end_time || t+seconds > self.end) && !exclude_end?
      TimeInterval.new(t, end_time, !inclusive) }
end
step(n, &blk) click to toggle source
# File lib/timerage/time_interval.rb, line 27
def step(n, &blk)
  if block_given?
    time_enumerator(n).each(&blk)
  else
    time_enumerator(n)
  end
end
to_time_interval() click to toggle source
# File lib/timerage/time_interval.rb, line 16
def to_time_interval
  self
end

Protected Instance Methods

rangeish?(an_obj) click to toggle source
# File lib/timerage/time_interval.rb, line 132
def rangeish?(an_obj)
  an_obj.respond_to?(:begin) &&
    an_obj.respond_to?(:end)
end
time_enumerator(step) click to toggle source
# File lib/timerage/time_interval.rb, line 137
def time_enumerator(step)
  next_offset = 0.seconds

  Enumerator.new do |y|
    while self.cover?(self.begin + next_offset)
      y << self.begin + next_offset
      next_offset += step
    end
  end
end