class TimeRange

Constants

VERSION

Attributes

time_zone[RW]

Public Class Methods

bucket(period, time, options = {}) click to toggle source
# File lib/timerange.rb, line 85
def self.bucket(period, time, options = {})
  time_zone = options[:time_zone] || TimeRange.time_zone || Time.zone || "Etc/UTC"
  day_start = options[:day_start] || 0
  week_start = options[:week_start] || 6

  week_start = [:mon, :tue, :wed, :thu, :fri, :sat, :sun].index((options[:week_start] || :sun).to_sym)
  if !week_start
    raise "Unrecognized :week_start option"
  end

  time = time.to_time.in_time_zone(time_zone) - day_start.hours

  time =
    case period.to_sym
    when :second
      time.change(usec: 0)
    when :minute
      time.change(sec: 0)
    when :hour
      time.change(min: 0)
    when :day
      time.beginning_of_day
    when :week
      # same logic as MySQL group
      weekday = (time.wday - 1) % 7
      (time - ((7 - week_start + weekday) % 7).days).midnight
    when :month
      time.beginning_of_month
    when :year
      time.beginning_of_year
    else
      raise "Invalid period"
    end

  time + day_start.hours
end
new(b = nil, e = Time.now, exclude_end = false, options = {}) click to toggle source
Calls superclass method
# File lib/timerange.rb, line 10
def initialize(b = nil, e = Time.now, exclude_end = false, options = {})
  if !b
    raise TypeError, "no implicit conversion of nil into Time"
  end

  if b.is_a?(Range)
    b, e, exclude_end = b.begin, b.end, b.exclude_end?
  end

  if b.is_a?(Hash)
    options, b, e, exclude_end = b, nil, nil, false
  elsif e.is_a?(Hash)
    options, e, exclude_end = e, Time.now, false
  end

  time_zone = options[:time_zone] || (b.respond_to?(:time_zone) && b.time_zone) || TimeRange.time_zone || Time.zone || "Etc/UTC"
  if time_zone.is_a?(ActiveSupport::TimeZone) or (time_zone = ActiveSupport::TimeZone[time_zone])
    # do nothing
  else
    raise "Unrecognized time zone"
  end

  b = time_zone.parse(b) if b.is_a?(String)
  e = time_zone.parse(e) if e.is_a?(String)
  b = b.in_time_zone(time_zone)
  e = e.in_time_zone(time_zone)

  if options[:duration]
    e = b + options[:duration]
    exclude_end = true
  end
  if options[:within]
    e = b + options[:within]
    b -= options[:within]
    exclude_end = false
  end

  @options = options.merge(time_zone: time_zone)

  super(b, e, exclude_end)
end
today(options = {}) click to toggle source
# File lib/timerange.rb, line 122
def self.today(options = {})
  date = Time.now
  new(date, date, options).expand(:day)
end
yesterday(options = {}) click to toggle source
# File lib/timerange.rb, line 127
def self.yesterday(options = {})
  date = Time.now - 1.day
  new(date, date, options).expand(:day)
end

Public Instance Methods

+(period) click to toggle source
# File lib/timerange.rb, line 132
def +(period)
  self.class.new(self.begin + period, self.end + period, exclude_end?)
end
-(period) click to toggle source
# File lib/timerange.rb, line 136
def -(period)
  self.class.new(self.begin - period, self.end - period, exclude_end?)
end
bucket(period, time, options = {}) click to toggle source
# File lib/timerange.rb, line 81
def bucket(period, time, options = {})
  self.class.bucket(period, time, @options.merge(options))
end
expand(period, options = {}) click to toggle source
# File lib/timerange.rb, line 65
def expand(period, options = {})
  e =
    if exclude_end? and self.end == bucket(period, self.end, options)
      self.end
    else
      bucket(period, self.end + 1.send(period), options)
    end
  self.class.new(bucket(period, self.begin, options), e, true, @options.merge(options))
end
expand_start(period, options = {}) click to toggle source
# File lib/timerange.rb, line 75
def expand_start(period, options = {})
  e = self.end
  e = e.in_time_zone(options[:time_zone]) if options[:time_zone]
  self.class.new(bucket(period, self.begin, options), e, exclude_end?, @options.merge(options))
end
step(period, options = {}) { |last| ... } click to toggle source

should step expand by default? TODO return enum

# File lib/timerange.rb, line 54
def step(period, options = {}, &block)
  period = period.is_a?(Symbol) || period.is_a?(String) ? 1.send(period) : period
  arr = [self.begin]
  yield(arr.last) if block_given?
  while v = arr.last + period and cover?(v)
    yield(v) if block_given?
    arr << v
  end
  arr
end