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
from
andto
. -
#exclude_end? ⇒ Boolean
Whether sequence was created from exclude-end range (and, therefore, will exclude
to
when 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) @options = .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 |