Class: TimeMath::Sequence
- Inherits:
-
Object
- Object
- TimeMath::Sequence
- 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(2016-05-01 13:30:00 +0300...2016-05-04 18:20:00 +0300)>
Now, you can use it:
seq.to_a
# => [2016-05-01 13:30:00 +0300, 2016-05-02 13:30:00 +0300, 2016-05-03 13:30:00 +0300, 2016-05-04 13:30:00 +0300]
-- it's an "each day start between from and to". As you can see,
the period start is the same as in from.
You can expand from and to to nearest round unit by #expand method
or :expand option:
seq..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]
# or:
seq = TimeMath.day.sequence(from...to, expand: true)
# => #<TimeMath::Sequence(2016-05-01 00:00:00 +0300...2016-05-05 00:00:00 +0300)>
seq.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]
# ^ note that `to` is excluded.
# You can include it by creating sequence from including-end range:
seq = TimeMath.day.sequence(from..to, expand: true)
# => #<TimeMath::Sequence(:day, 2016-05-01 00:00:00 +0300..2016-05-05 00:00:00 +0300)>
seq.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, 2016-05-05 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 = TimeMath.day.sequence(from...to)
seq.pairs
# => [[2016-05-01 13:30:00 +0300, 2016-05-02 13:30:00 +0300], [2016-05-02 13:30:00 +0300, 2016-05-03 13:30:00 +0300], [2016-05-03 13:30:00 +0300, 2016-05-04 13:30:00 +0300], [2016-05-04 13:30:00 +0300, 2016-05-04 18:20:00 +0300]]
seq.ranges
# => [2016-05-01 13:30:00 +0300...2016-05-02 13:30:00 +0300, 2016-05-02 13:30:00 +0300...2016-05-03 13:30:00 +0300, 2016-05-03 13:30:00 +0300...2016-05-04 13:30:00 +0300, 2016-05-04 13:30:00 +0300...2016-05-04 18:20: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, expand: true).advance(:hour, 5).decrease(:min, 20)
# => #<TimeMath::Sequence(:day, 2016-05-01 00:00:00 +0300...2016-05-05 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, 2016-05-04 04:40:00 +0300]
Instance Attribute Summary collapse
-
#from ⇒ Object
readonly
Returns the value of attribute from.
-
#op ⇒ Object
readonly
Returns the value of attribute op.
-
#to ⇒ Object
readonly
Returns the value of attribute to.
-
#unit ⇒ Object
readonly
Returns the value of attribute unit.
Instance Method Summary collapse
-
#==(other) ⇒ Boolean
Compares two sequences, considering their start, end, unit and operations.
-
#advance(unit, amount = 1) ⇒ Sequence
Non-destructive version of #advance!.
-
#advance!(unit, amount = 1) ⇒ self
Adds Units::Base#advance to list of operations to apply to sequence items.
-
#ceil(unit, span = 1) ⇒ Sequence
Non-destructive version of #ceil!.
-
#ceil!(unit, span = 1) ⇒ self
Adds Units::Base#ceil to list of operations to apply to sequence items.
-
#decrease(unit, amount = 1) ⇒ Sequence
Non-destructive version of #decrease!.
-
#decrease!(unit, amount = 1) ⇒ self
Adds Units::Base#decrease to list of operations to apply to sequence items.
-
#each {|op.call(to)| ... } ⇒ Enumerator<Time, or Date, or DateTime>
Enumerates time unit between
fromandto. -
#exclude_end? ⇒ Boolean
Whether sequence was created from exclude-end range (and, therefore, will exclude
towhen converted to array). -
#expand ⇒ Sequence
Creates new sequence with ends rounded to nearest unit.
-
#expand! ⇒ self
Expand sequence ends to nearest round unit.
-
#floor(unit, span = 1) ⇒ Sequence
Non-destructive version of #floor!.
-
#floor!(unit, span = 1) ⇒ self
Adds Units::Base#floor to list of operations to apply to sequence items.
-
#initialize(unit, range, options = {}) ⇒ Sequence
constructor
Creates a sequence.
- #inspect ⇒ Object
-
#next(unit, span = 1) ⇒ Sequence
Non-destructive version of #next!.
-
#next!(unit, span = 1) ⇒ self
Adds Units::Base#next to list of operations to apply to sequence items.
-
#pairs ⇒ Array<Array>
Creates an array of pairs (time unit start, time unit end) between from and to.
-
#prev(unit, span = 1) ⇒ Sequence
Non-destructive version of #prev!.
-
#prev!(unit, span = 1) ⇒ self
Adds Units::Base#prev to list of operations to apply to sequence items.
-
#ranges ⇒ Array<Range>
Creates an array of Ranges (time unit start...time unit end) between from and to.
-
#round(unit, span = 1) ⇒ Sequence
Non-destructive version of #round!.
-
#round!(unit, span = 1) ⇒ self
Adds Units::Base#round to list of operations to apply to sequence items.
Constructor Details
#initialize(unit, range, options = {}) ⇒ Sequence
Creates a sequence. Typically, it is easier to to it with Units::Base#sequence, like this:
TimeMath.day.sequence(from...to)
83 84 85 86 87 88 89 90 |
# File 'lib/time_math/sequence.rb', line 83 def initialize(unit, range, = {}) @unit = Units.get(unit) @from, @to, @exclude_end = process_range(range) = .dup if [:expand] @op = Op.new end |
Instance Attribute Details
#from ⇒ Object (readonly)
Returns the value of attribute from.
99 100 101 |
# File 'lib/time_math/sequence.rb', line 99 def from @from end |
#op ⇒ Object (readonly)
Returns the value of attribute op.
99 100 101 |
# File 'lib/time_math/sequence.rb', line 99 def op @op end |
#to ⇒ Object (readonly)
Returns the value of attribute to.
99 100 101 |
# File 'lib/time_math/sequence.rb', line 99 def to @to end |
#unit ⇒ Object (readonly)
Returns the value of attribute unit.
99 100 101 |
# File 'lib/time_math/sequence.rb', line 99 def unit @unit end |
Instance Method Details
#==(other) ⇒ Boolean
Compares two sequences, considering their start, end, unit and operations.
106 107 108 109 110 111 |
# File 'lib/time_math/sequence.rb', line 106 def ==(other) # rubocop:disable Metrics/AbcSize self.class == other.class && unit == other.unit && from == other.from && to == other.to && exclude_end? == other.exclude_end? && op == other.op end |
#advance(unit, amount = 1) ⇒ Sequence
Non-destructive version of #advance!.
222 223 224 225 226 227 228 229 230 231 |
# File 'lib/time_math/sequence.rb', line 222 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.
222 223 224 225 226 227 228 229 230 231 |
# File 'lib/time_math/sequence.rb', line 222 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!.
222 223 224 225 226 227 228 229 230 231 |
# File 'lib/time_math/sequence.rb', line 222 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.
222 223 224 225 226 227 228 229 230 231 |
# File 'lib/time_math/sequence.rb', line 222 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!.
222 223 224 225 226 227 228 229 230 231 |
# File 'lib/time_math/sequence.rb', line 222 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.
222 223 224 225 226 227 228 229 230 231 |
# File 'lib/time_math/sequence.rb', line 222 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 |
#each {|op.call(to)| ... } ⇒ Enumerator<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.
238 239 240 241 242 243 244 245 246 247 248 |
# File 'lib/time_math/sequence.rb', line 238 def each return to_enum(:each) unless block_given? iter = from while iter < to yield(op.call(iter)) iter = unit.advance(iter) end yield(op.call(to)) unless exclude_end? end |
#exclude_end? ⇒ Boolean
Whether sequence was created from exclude-end range (and, therefore,
will exclude to when converted to array).
115 116 117 |
# File 'lib/time_math/sequence.rb', line 115 def exclude_end? @exclude_end end |
#expand ⇒ Sequence
Creates new sequence with ends rounded to nearest unit.
132 133 134 |
# File 'lib/time_math/sequence.rb', line 132 def dup. end |
#expand! ⇒ self
Expand sequence ends to nearest round unit.
122 123 124 125 126 127 |
# File 'lib/time_math/sequence.rb', line 122 def @from = unit.floor(from) @to = unit.ceil(to) self end |
#floor(unit, span = 1) ⇒ Sequence
Non-destructive version of #floor!.
222 223 224 225 226 227 228 229 230 231 |
# File 'lib/time_math/sequence.rb', line 222 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.
222 223 224 225 226 227 228 229 230 231 |
# File 'lib/time_math/sequence.rb', line 222 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 |
#inspect ⇒ Object
269 270 271 272 273 |
# File 'lib/time_math/sequence.rb', line 269 def inspect ops = op.inspect_operations ops = '.' + ops unless ops.empty? "#<#{self.class}(#{unit.name.inspect}, #{from}#{exclude_end? ? '...' : '..'}#{to})#{ops}>" end |
#next(unit, span = 1) ⇒ Sequence
Non-destructive version of #next!.
222 223 224 225 226 227 228 229 230 231 |
# File 'lib/time_math/sequence.rb', line 222 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.
222 223 224 225 226 227 228 229 230 231 |
# File 'lib/time_math/sequence.rb', line 222 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 |
#pairs ⇒ Array<Array>
Creates an array of pairs (time unit start, time unit end) between from and to.
256 257 258 259 |
# File 'lib/time_math/sequence.rb', line 256 def pairs seq = to_a seq.zip(seq[1..-1] + [to]) end |
#prev(unit, span = 1) ⇒ Sequence
Non-destructive version of #prev!.
222 223 224 225 226 227 228 229 230 231 |
# File 'lib/time_math/sequence.rb', line 222 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.
222 223 224 225 226 227 228 229 230 231 |
# File 'lib/time_math/sequence.rb', line 222 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 |
#ranges ⇒ Array<Range>
Creates an array of Ranges (time unit start...time unit end) between from and to.
265 266 267 |
# File 'lib/time_math/sequence.rb', line 265 def ranges pairs.map { |b, e| (b...e) } end |
#round(unit, span = 1) ⇒ Sequence
Non-destructive version of #round!.
222 223 224 225 226 227 228 229 230 231 |
# File 'lib/time_math/sequence.rb', line 222 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.
222 223 224 225 226 227 228 229 230 231 |
# File 'lib/time_math/sequence.rb', line 222 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 |