class TimeRange

An enhanced, Range-type class that provides useful methods that apply to time-based objects.

@since 0.0.1

Constants

VERSION

Public Class Methods

new(b, e, exclude_end = false) click to toggle source
Calls superclass method
# File lib/time_range.rb, line 11
def initialize(b, e, exclude_end = false)
  raise TypeError unless [b, e].all? { |arg| arg.is_a?(Time) }

  valid_time = if exclude_end
                 (e - 1) >= b
               else
                 e >= b
               end

  raise ArgumentError unless valid_time

  super
end

Public Instance Methods

==(other) click to toggle source

Reimplementation of Range#== to account for time ranges excluding end being one second shorter than their end implies.

@param [TimeRange] time_range time range to compare for equality @return [Boolean] whether contents of two TimeRanges match

Calls superclass method
# File lib/time_range.rb, line 30
def ==(other)
  return false unless other.is_a?(self.class)

  if exclude_end? || other.exclude_end?
    return self.begin == other.begin && max == other.max
  end

  super
end
Also aliased as: eql?
dates() click to toggle source

Returns the dates in the current TimeRange as a Range of Dates.

@return [Range] the dates in the current time range

# File lib/time_range.rb, line 116
def dates
  b_date = Date.civil(self.begin.year, self.begin.month, self.begin.day)
  e_date = Date.civil(max.year, max.month, max.day)

  b_date..e_date
end
duration() click to toggle source

The duration of the time range in seconds.

@return [Float] the number of seconds in the time range

# File lib/time_range.rb, line 61
def duration
  max - self.begin
end
encapsulated_by?(time_range) click to toggle source

Reverse of encapsulates?, checks if the current time range is encapsulated by another.

@param [TimeRange] time_range time range to compare against encapsulation @return [Boolean] whether the target range encapsulates this one

# File lib/time_range.rb, line 94
def encapsulated_by?(time_range)
  raise TypeError unless time_range.is_a?(TimeRange)

  time_range.encapsulates?(self)
end
encapsulates?(time_range) click to toggle source

Compares another time range for complete encapsulation. A time range is considered encapsulated if it begins and ends within this one, including if the ranges match exactly.

@param [TimeRange] time_range time range to compare for encapsulation @return [Boolean] whether the target range is encapsulated

# File lib/time_range.rb, line 83
def encapsulates?(time_range)
  raise TypeError unless time_range.is_a?(TimeRange)

  self.begin <= time_range.begin && max >= time_range.max
end
eql?(other)
Alias for: ==
max() click to toggle source

Reimplementation of Range#max. TimeRange makes one assumption; that ranges excluding end should be one second shorter than those that don't.

Normal Ranges simply TypeError when excluding_end is true. However, since Ruby's Time methods assume seconds anyway, it is reasonable to use seconds here.

Doing so enables the implementation of a number of useful TimeRange methods.

@return [Time] the highest time included in the range

Calls superclass method
# File lib/time_range.rb, line 52
def max
  return self.end - 1 if exclude_end?

  super
end
overlap_with(time_range) click to toggle source

Returns the overlap between this and the argument as a new time range.

@param [TimeRange] time_range time range to compare for encapsulation @return [TimeRange, nil] the overlap in a TimeRange or nil if none occurs

# File lib/time_range.rb, line 104
def overlap_with(time_range)
  raise TypeError unless time_range.is_a?(TimeRange)

  self.class.new(
    [self.begin, time_range.begin].max,
    [max, time_range.max].min
  ) if overlaps?(time_range)
end
overlaps?(time_range) click to toggle source

Compares another time range for any kind of overlap; partial or complete.

@param [TimeRange] time_range time range to compare for overlap @return [Boolean] whether contents of two TimeRanges overlap

# File lib/time_range.rb, line 69
def overlaps?(time_range)
  raise TypeError unless time_range.is_a?(TimeRange)

  %w(begins_within? ends_within? encapsulates?).any? do |condition|
    send(condition, time_range)
  end
end

Private Instance Methods

begins_within?(time_range) click to toggle source
# File lib/time_range.rb, line 125
def begins_within?(time_range)
  self.begin >= time_range.begin && self.begin <= time_range.max
end
ends_within?(time_range) click to toggle source
# File lib/time_range.rb, line 129
def ends_within?(time_range)
  max <= time_range.max && max >= time_range.begin
end