Class: Sleek::Timeframe

Inherits:
Object
  • Object
show all
Defined in:
lib/sleek/timeframe.rb

Constant Summary collapse

REGEXP =
/(this|previous)_((\d+)_)?(minute|hour|day|week|month)s?/

Class Method Summary collapse

Class Method Details

.parse(timeframe, timezone = nil) ⇒ Object

Internal: Process timeframe string to make up a range.

timeframe - the String matching

(this|previous)_((\d+)_)?(minute|hour|day|week|month)s?

timezone - the optional String TZ identifier. See

`ActiveSupport::TimeZone`.


42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/sleek/timeframe.rb', line 42

def parse(timeframe, timezone = nil)
  _, category, _, number, interval = *timeframe.match(REGEXP)

  unless category && interval
    raise ArgumentError, 'special timeframe string is malformed'
  end

  number ||= 1
  number = number.to_i

  range = range_from_interval(interval, number, timezone)
  range = range - 1.send(interval) if category == 'previous'
  range
end

.range_from_interval(interval, number = 1, timezone = nil) ⇒ Object

Internal: Create a time range from interval type & number of intervals.

interval - the String interval type name. Valid values are

minute, hour, day, week, and month.

number - the Integer number of periods. timezone - the optional String TZ identifier. See

`ActiveSupport::TimeZone`.

Returns the range of TimeWithZone objects.



67
68
69
70
71
72
73
74
75
# File 'lib/sleek/timeframe.rb', line 67

def range_from_interval(interval, number = 1, timezone = nil)
  timezone ||= 'UTC'
  now = ActiveSupport::TimeZone.new(timezone).now

  end_point = now.send("end_of_#{interval}").round
  start_point = end_point - number.send(interval)

  start_point..end_point
end

.to_range(timeframe, timezone = nil) ⇒ Object

Internal: Transform the object passed to Timeframe initializer into a range of Time objects.

timeframe - either a Range of Time objects, a two-element array

of Time Objects, or a special string.

timezone - the optional String TZ identifier. See

`ActiveSupport::TimeZone`.

Examples

Timeframe.to_range :this_2_days

Timeframe.to_range :previous_hour

Timeframe.to_range :this_day, timezone: 'US/Pacific'

Raises ArgumentError if passed object can’t be processed.



23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/sleek/timeframe.rb', line 23

def to_range(timeframe, timezone = nil)
  case timeframe
  when proc { |tf| tf.is_a?(Range) && tf.time_range? }
    t = timeframe
  when proc { |tf| tf.is_a?(Array) && tf.size == 2 && tf.count { |_tf| _tf.is_a?(Time) } == 2 }
    t = timeframe.first..timeframe.last
  when String, Symbol
    t = parse(timeframe.to_s, timezone)
  else
    raise ArgumentError, "wrong timeframe - #{timeframe}"
  end
end