Class: TimeMath::Sequence

Inherits:
Object
  • Object
show all
Includes:
Enumerable
Defined in:
lib/time_math/sequence.rb

Overview

Sequence represents a sequential units of time between two points. It has several options and convenience methods for creating arrays of data.

Basic usage example:

from = Time.parse('2016-05-01 13:30')
to = Time.parse('2016-05-04 18:20')
seq = TimeMath.day.sequence(from...to)
# => #<TimeMath::Sequence day (2016-05-01 00:00:00 +0300-2016 - 2016-05-04 00:00:00 +0300)>

Now, you can use it:

seq.to_a
# => [2016-05-01 00:00:00 +0300, 2016-05-02 00:00:00 +0300, 2016-05-03 00:00:00 +0300]

-- it's an "each day start between from and to".

Depending of including/excluding of range, you will, or will not receive period that includes to:

TimeMath.day.sequence(from..to).to_a
# => [2016-05-01 00:00:00 +0300, 2016-05-02 00:00:00 +0300, 2016-05-03 00:00:00 +0300, 2016-05-04 00:00:00 +0300]

Besides each period beginning, you can also request pairs of begin/end of a period, either as an array of arrays, or array of ranges:

seq.pairs
# => [[2016-05-01 00:00:00 +0300, 2016-05-02 00:00:00 +0300], [2016-05-02 00:00:00 +0300, 2016-05-03 00:00:00 +0300], [2016-05-03 00:00:00 +0300, 2016-05-04 00:00:00 +0300]]
seq.ranges
# => [2016-05-01 00:00:00 +0300...2016-05-02 00:00:00 +0300, 2016-05-02 00:00:00 +0300...2016-05-03 00:00:00 +0300, 2016-05-03 00:00:00 +0300...2016-05-04 00:00:00 +0300]

It is pretty convenient for filtering data from databases or APIs: TimeMath creates list of filtering ranges in a blink.

Sequence also supports any item-updating operations in the same fashion Op does:

seq = TimeMath.day.sequence(from...to).advance(:hour, 5).decrease(:min, 20)
# => #<TimeMath::Sequence day (2016-05-01 00:00:00 +0300 - 2016-05-03 00:00:00 +0300).advance(:hour, 5).decrease(:min, 20)>
seq.to_a
# => [2016-05-01 04:40:00 +0300, 2016-05-02 04:40:00 +0300, 2016-05-03 04:40:00 +0300]

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(unit, range) ⇒ Sequence

Creates a sequence. Typically, it is easier to do it with Units::Base#sequence, like this:

TimeMath.day.sequence(from...to)

Parameters:

  • unit (Symbol)
  • range (Range)

    range of time-y values (Time, Date, DateTime); note that range with inclusive and exclusive and will produce different sequences.



66
67
68
69
70
# File 'lib/time_math/sequence.rb', line 66

def initialize(unit, range)
  @unit = Units.get(unit)
  @from, @to = process_range(range)
  @op = Op.new
end

Instance Attribute Details

#fromObject (readonly)

Returns the value of attribute from.



79
80
81
# File 'lib/time_math/sequence.rb', line 79

def from
  @from
end

#opObject (readonly)

Returns the value of attribute op.



79
80
81
# File 'lib/time_math/sequence.rb', line 79

def op
  @op
end

#toObject (readonly)

Returns the value of attribute to.



79
80
81
# File 'lib/time_math/sequence.rb', line 79

def to
  @to
end

#unitObject (readonly)

Returns the value of attribute unit.



79
80
81
# File 'lib/time_math/sequence.rb', line 79

def unit
  @unit
end

Instance Method Details

#==(other) ⇒ Boolean

Compares two sequences, considering their start, end, unit and operations.

Parameters:

Returns:

  • (Boolean)


86
87
88
89
90
# File 'lib/time_math/sequence.rb', line 86

def ==(other) # rubocop:disable Metrics/AbcSize
  self.class == other.class && unit == other.unit &&
    from == other.from && to == other.to &&
    op == other.op
end

#advance(unit, amount = 1) ⇒ Sequence

Non-destructive version of #advance!.

Parameters:

  • unit (Symbol)
  • amount (Numeric) (defaults to: 1)

    how many units to advance.

Returns:



178
179
180
181
182
183
184
185
186
187
# File 'lib/time_math/sequence.rb', line 178

Op::OPERATIONS.each do |operation|
  define_method "#{operation}!" do |*arg|
    @op.send("#{operation}!", *arg)
    self
  end

  define_method operation do |*arg|
    dup.send("#{operation}!", *arg)
  end
end

#advance!(unit, amount = 1) ⇒ self

Adds Units::Base#advance to list of operations to apply to sequence items.

Parameters:

  • unit (Symbol)
  • amount (Numeric) (defaults to: 1)

    how many units to advance.

Returns:

  • (self)


178
179
180
181
182
183
184
185
186
187
# File 'lib/time_math/sequence.rb', line 178

Op::OPERATIONS.each do |operation|
  define_method "#{operation}!" do |*arg|
    @op.send("#{operation}!", *arg)
    self
  end

  define_method operation do |*arg|
    dup.send("#{operation}!", *arg)
  end
end

#ceil(unit, span = 1) ⇒ Sequence

Non-destructive version of #ceil!.

Parameters:

  • unit (Symbol)
  • span (Numeric) (defaults to: 1)

    how many units to ceil to.

Returns:



178
179
180
181
182
183
184
185
186
187
# File 'lib/time_math/sequence.rb', line 178

Op::OPERATIONS.each do |operation|
  define_method "#{operation}!" do |*arg|
    @op.send("#{operation}!", *arg)
    self
  end

  define_method operation do |*arg|
    dup.send("#{operation}!", *arg)
  end
end

#ceil!(unit, span = 1) ⇒ self

Adds Units::Base#ceil to list of operations to apply to sequence items.

Parameters:

  • unit (Symbol)
  • span (Numeric) (defaults to: 1)

    how many units to ceil to.

Returns:

  • (self)


178
179
180
181
182
183
184
185
186
187
# File 'lib/time_math/sequence.rb', line 178

Op::OPERATIONS.each do |operation|
  define_method "#{operation}!" do |*arg|
    @op.send("#{operation}!", *arg)
    self
  end

  define_method operation do |*arg|
    dup.send("#{operation}!", *arg)
  end
end

#decrease(unit, amount = 1) ⇒ Sequence

Non-destructive version of #decrease!.

Parameters:

  • unit (Symbol)
  • amount (Numeric) (defaults to: 1)

    how many units to decrease.

Returns:



178
179
180
181
182
183
184
185
186
187
# File 'lib/time_math/sequence.rb', line 178

Op::OPERATIONS.each do |operation|
  define_method "#{operation}!" do |*arg|
    @op.send("#{operation}!", *arg)
    self
  end

  define_method operation do |*arg|
    dup.send("#{operation}!", *arg)
  end
end

#decrease!(unit, amount = 1) ⇒ self

Adds Units::Base#decrease to list of operations to apply to sequence items.

Parameters:

  • unit (Symbol)
  • amount (Numeric) (defaults to: 1)

    how many units to decrease.

Returns:

  • (self)


178
179
180
181
182
183
184
185
186
187
# File 'lib/time_math/sequence.rb', line 178

Op::OPERATIONS.each do |operation|
  define_method "#{operation}!" do |*arg|
    @op.send("#{operation}!", *arg)
    self
  end

  define_method operation do |*arg|
    dup.send("#{operation}!", *arg)
  end
end

#eachEnumerator<Time, or Date, or DateTime>

Enumerates time unit between from and to. They will have same granularity as from (e.g. if unit is day and from is 2016-05-01 13:30, each of return values will be next day at 13:30), unless sequence is not set to floor values.

Returns:

  • (Enumerator<Time, or Date, or DateTime>)


194
195
196
197
198
199
200
201
202
203
# File 'lib/time_math/sequence.rb', line 194

def each
  return to_enum(:each) unless block_given?

  iter = from
  while iter <= to
    yield(op.call(iter))

    iter = unit.advance(iter)
  end
end

#floor(unit, span = 1) ⇒ Sequence

Non-destructive version of #floor!.

Parameters:

  • unit (Symbol)
  • span (Numeric) (defaults to: 1)

    how many units to floor to.

Returns:



178
179
180
181
182
183
184
185
186
187
# File 'lib/time_math/sequence.rb', line 178

Op::OPERATIONS.each do |operation|
  define_method "#{operation}!" do |*arg|
    @op.send("#{operation}!", *arg)
    self
  end

  define_method operation do |*arg|
    dup.send("#{operation}!", *arg)
  end
end

#floor!(unit, span = 1) ⇒ self

Adds Units::Base#floor to list of operations to apply to sequence items.

Parameters:

  • unit (Symbol)
  • span (Numeric) (defaults to: 1)

    how many units to floor to.

Returns:

  • (self)


178
179
180
181
182
183
184
185
186
187
# File 'lib/time_math/sequence.rb', line 178

Op::OPERATIONS.each do |operation|
  define_method "#{operation}!" do |*arg|
    @op.send("#{operation}!", *arg)
    self
  end

  define_method operation do |*arg|
    dup.send("#{operation}!", *arg)
  end
end

#inspectObject



224
225
226
227
228
# File 'lib/time_math/sequence.rb', line 224

def inspect
  ops = op.inspect_operations
  ops = '.' + ops unless ops.empty?
  "#<#{self.class} #{unit.name} (#{from} - #{to})#{ops}>"
end

#next(unit, span = 1) ⇒ Sequence

Non-destructive version of #next!.

Parameters:

  • unit (Symbol)
  • span (Numeric) (defaults to: 1)

    how many units to ceil to.

Returns:



178
179
180
181
182
183
184
185
186
187
# File 'lib/time_math/sequence.rb', line 178

Op::OPERATIONS.each do |operation|
  define_method "#{operation}!" do |*arg|
    @op.send("#{operation}!", *arg)
    self
  end

  define_method operation do |*arg|
    dup.send("#{operation}!", *arg)
  end
end

#next!(unit, span = 1) ⇒ self

Adds Units::Base#next to list of operations to apply to sequence items.

Parameters:

  • unit (Symbol)
  • span (Numeric) (defaults to: 1)

    how many units to ceil to.

Returns:

  • (self)


178
179
180
181
182
183
184
185
186
187
# File 'lib/time_math/sequence.rb', line 178

Op::OPERATIONS.each do |operation|
  define_method "#{operation}!" do |*arg|
    @op.send("#{operation}!", *arg)
    self
  end

  define_method operation do |*arg|
    dup.send("#{operation}!", *arg)
  end
end

#pairsArray<Array>

Creates an array of pairs (time unit start, time unit end) between from and to.

Returns:

  • (Array<Array>)


211
212
213
214
# File 'lib/time_math/sequence.rb', line 211

def pairs
  seq = to_a
  seq.zip([*seq[1..-1], unit.advance(to)])
end

#prev(unit, span = 1) ⇒ Sequence

Non-destructive version of #prev!.

Parameters:

  • unit (Symbol)
  • span (Numeric) (defaults to: 1)

    how many units to floor to.

Returns:



178
179
180
181
182
183
184
185
186
187
# File 'lib/time_math/sequence.rb', line 178

Op::OPERATIONS.each do |operation|
  define_method "#{operation}!" do |*arg|
    @op.send("#{operation}!", *arg)
    self
  end

  define_method operation do |*arg|
    dup.send("#{operation}!", *arg)
  end
end

#prev!(unit, span = 1) ⇒ self

Adds Units::Base#prev to list of operations to apply to sequence items.

Parameters:

  • unit (Symbol)
  • span (Numeric) (defaults to: 1)

    how many units to floor to.

Returns:

  • (self)


178
179
180
181
182
183
184
185
186
187
# File 'lib/time_math/sequence.rb', line 178

Op::OPERATIONS.each do |operation|
  define_method "#{operation}!" do |*arg|
    @op.send("#{operation}!", *arg)
    self
  end

  define_method operation do |*arg|
    dup.send("#{operation}!", *arg)
  end
end

#rangesArray<Range>

Creates an array of Ranges (time unit start...time unit end) between from and to.

Returns:

  • (Array<Range>)


220
221
222
# File 'lib/time_math/sequence.rb', line 220

def ranges
  pairs.map { |b, e| (b...e) }
end

#round(unit, span = 1) ⇒ Sequence

Non-destructive version of #round!.

Parameters:

  • unit (Symbol)
  • span (Numeric) (defaults to: 1)

    how many units to round to.

Returns:



178
179
180
181
182
183
184
185
186
187
# File 'lib/time_math/sequence.rb', line 178

Op::OPERATIONS.each do |operation|
  define_method "#{operation}!" do |*arg|
    @op.send("#{operation}!", *arg)
    self
  end

  define_method operation do |*arg|
    dup.send("#{operation}!", *arg)
  end
end

#round!(unit, span = 1) ⇒ self

Adds Units::Base#round to list of operations to apply to sequence items.

Parameters:

  • unit (Symbol)
  • span (Numeric) (defaults to: 1)

    how many units to round to.

Returns:

  • (self)


178
179
180
181
182
183
184
185
186
187
# File 'lib/time_math/sequence.rb', line 178

Op::OPERATIONS.each do |operation|
  define_method "#{operation}!" do |*arg|
    @op.send("#{operation}!", *arg)
    self
  end

  define_method operation do |*arg|
    dup.send("#{operation}!", *arg)
  end
end