time_math2 0.0.8 → 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/lib/time_math/resamplers.rb +23 -18
- data/lib/time_math/sequence.rb +26 -66
- data/lib/time_math/units/base.rb +4 -11
- data/lib/time_math/version.rb +1 -1
- data/time_math2.gemspec +2 -0
- metadata +3 -3
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA1:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: f2e42b79bda1365a78f8c74b1b2d41af59f4c5c0
         | 
| 4 | 
            +
              data.tar.gz: b2dcd6572c88be32bfbff1f9a3f15cda929551b9
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 987ddc51e856db1f2f9baa77d68beb189b7a2f6193a82d5839cf11b3e4b9f989d8fe676d4539087a60bbda75e4779f90a7c8d0b706a5d2cef1c85123c8fd9f6b
         | 
| 7 | 
            +
              data.tar.gz: 0d5a36c6e120c1244ae40a768b13f499455e855890a46013674464e9d6939b7797ef14aed268a05491e29e98be4249467bb112d5b29381611606be7346f4632e
         | 
    
        data/CHANGELOG.md
    CHANGED
    
    | @@ -1,5 +1,10 @@ | |
| 1 1 | 
             
            # TimeMath Changelog
         | 
| 2 2 |  | 
| 3 | 
            +
            # 0.1.0 (2017-07-30)
         | 
| 4 | 
            +
             | 
| 5 | 
            +
            * Update sequences logic to be, well... More logical (Thanks @kenn again for meaningful discussion!);
         | 
| 6 | 
            +
            * Various code cleanups.
         | 
| 7 | 
            +
             | 
| 3 8 | 
             
            # 0.0.8 (2017-06-02)
         | 
| 4 9 |  | 
| 5 10 | 
             
            * Fix `Units::Base#measure` to correctly measure negative distances (e.g. from > to, thanks @kenn for
         | 
    
        data/lib/time_math/resamplers.rb
    CHANGED
    
    | @@ -2,14 +2,13 @@ module TimeMath | |
| 2 2 | 
             
              # @private
         | 
| 3 3 | 
             
              class Resampler
         | 
| 4 4 | 
             
                class << self
         | 
| 5 | 
            -
                  def call( | 
| 6 | 
            -
                     | 
| 7 | 
            -
                      ArrayResampler. | 
| 8 | 
            -
             | 
| 9 | 
            -
                       | 
| 10 | 
            -
             | 
| 11 | 
            -
             | 
| 12 | 
            -
                    end
         | 
| 5 | 
            +
                  def call(unit, array_or_hash, symbol = nil, &block)
         | 
| 6 | 
            +
                    resampler =
         | 
| 7 | 
            +
                      ArrayResampler.try(unit, array_or_hash) ||
         | 
| 8 | 
            +
                      HashResampler.try(unit, array_or_hash) or
         | 
| 9 | 
            +
                      raise ArgumentError, "Expected array of timestamps or hash with timestamp keys, #{array_or_hash} got"
         | 
| 10 | 
            +
             | 
| 11 | 
            +
                    resampler.call(symbol, &block)
         | 
| 13 12 | 
             
                  end
         | 
| 14 13 | 
             
                end
         | 
| 15 14 |  | 
| @@ -17,29 +16,30 @@ module TimeMath | |
| 17 16 | 
             
                  @unit = Units.get(unit)
         | 
| 18 17 | 
             
                end
         | 
| 19 18 |  | 
| 20 | 
            -
                 | 
| 21 | 
            -
             | 
| 22 | 
            -
                def sequence
         | 
| 23 | 
            -
                  @sequence ||= @unit.sequence(from...to, expand: true)
         | 
| 19 | 
            +
                def call
         | 
| 20 | 
            +
                  raise NotImplementedError
         | 
| 24 21 | 
             
                end
         | 
| 25 22 |  | 
| 26 | 
            -
                 | 
| 27 | 
            -
                  timestamps.min
         | 
| 28 | 
            -
                end
         | 
| 23 | 
            +
                private
         | 
| 29 24 |  | 
| 30 | 
            -
                def  | 
| 31 | 
            -
                  @unit. | 
| 25 | 
            +
                def sequence
         | 
| 26 | 
            +
                  @sequence ||= @unit.sequence(timestamps.min..timestamps.max)
         | 
| 32 27 | 
             
                end
         | 
| 33 28 | 
             
              end
         | 
| 34 29 |  | 
| 35 30 | 
             
              # @private
         | 
| 36 31 | 
             
              class ArrayResampler < Resampler
         | 
| 32 | 
            +
                def self.try(unit, array)
         | 
| 33 | 
            +
                  return nil unless array.is_a?(Array) && array.all?(&Util.method(:timey?))
         | 
| 34 | 
            +
                  new(unit, array)
         | 
| 35 | 
            +
                end
         | 
| 36 | 
            +
             | 
| 37 37 | 
             
                def initialize(unit, array)
         | 
| 38 38 | 
             
                  super(unit)
         | 
| 39 39 | 
             
                  @array = array
         | 
| 40 40 | 
             
                end
         | 
| 41 41 |  | 
| 42 | 
            -
                def call
         | 
| 42 | 
            +
                def call(*)
         | 
| 43 43 | 
             
                  sequence.to_a
         | 
| 44 44 | 
             
                end
         | 
| 45 45 |  | 
| @@ -52,6 +52,11 @@ module TimeMath | |
| 52 52 |  | 
| 53 53 | 
             
              # @private
         | 
| 54 54 | 
             
              class HashResampler < Resampler
         | 
| 55 | 
            +
                def self.try(unit, hash)
         | 
| 56 | 
            +
                  return nil unless hash.is_a?(Hash) && hash.keys.all?(&Util.method(:timey?))
         | 
| 57 | 
            +
                  new(unit, hash)
         | 
| 58 | 
            +
                end
         | 
| 59 | 
            +
             | 
| 55 60 | 
             
                def initialize(unit, hash)
         | 
| 56 61 | 
             
                  super(unit)
         | 
| 57 62 | 
             
                  @hash = hash
         | 
    
        data/lib/time_math/sequence.rb
    CHANGED
    
    | @@ -9,63 +9,49 @@ module TimeMath | |
| 9 9 | 
             
              # from = Time.parse('2016-05-01 13:30')
         | 
| 10 10 | 
             
              # to = Time.parse('2016-05-04 18:20')
         | 
| 11 11 | 
             
              # seq = TimeMath.day.sequence(from...to)
         | 
| 12 | 
            -
              # # => #<TimeMath::Sequence(2016-05-01  | 
| 12 | 
            +
              # # => #<TimeMath::Sequence day (2016-05-01 00:00:00 +0300-2016 - 2016-05-04 00:00:00 +0300)>
         | 
| 13 13 | 
             
              # ```
         | 
| 14 14 | 
             
              #
         | 
| 15 15 | 
             
              # Now, you can use it:
         | 
| 16 16 | 
             
              #
         | 
| 17 17 | 
             
              # ```ruby
         | 
| 18 18 | 
             
              # seq.to_a
         | 
| 19 | 
            -
              # # => [2016-05-01  | 
| 19 | 
            +
              # # => [2016-05-01 00:00:00 +0300, 2016-05-02 00:00:00 +0300, 2016-05-03 00:00:00 +0300]
         | 
| 20 20 | 
             
              # ```
         | 
| 21 | 
            -
              # -- it's an "each day start between from and to". | 
| 22 | 
            -
              # the period start is the same as in `from`.
         | 
| 21 | 
            +
              # -- it's an "each day start between from and to".
         | 
| 23 22 | 
             
              #
         | 
| 24 | 
            -
              #  | 
| 25 | 
            -
              # or `:expand` option:
         | 
| 23 | 
            +
              # Depending of including/excluding of range, you will, or will not receive period that includes `to`:
         | 
| 26 24 | 
             
              #
         | 
| 27 25 | 
             
              # ```ruby
         | 
| 28 | 
            -
              #  | 
| 26 | 
            +
              # TimeMath.day.sequence(from..to).to_a
         | 
| 29 27 | 
             
              # # => [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]
         | 
| 30 | 
            -
              # # or:
         | 
| 31 | 
            -
              # seq = TimeMath.day.sequence(from...to, expand: true)
         | 
| 32 | 
            -
              # # => #<TimeMath::Sequence(2016-05-01 00:00:00 +0300...2016-05-05 00:00:00 +0300)>
         | 
| 33 | 
            -
              # seq.to_a
         | 
| 34 | 
            -
              # # => [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]
         | 
| 35 | 
            -
              # # ^ note that `to` is excluded.
         | 
| 36 | 
            -
              # # You can include it by creating sequence from including-end range:
         | 
| 37 | 
            -
              # seq = TimeMath.day.sequence(from..to, expand: true)
         | 
| 38 | 
            -
              # # => #<TimeMath::Sequence(:day, 2016-05-01 00:00:00 +0300..2016-05-05 00:00:00 +0300)>
         | 
| 39 | 
            -
              # seq.to_a
         | 
| 40 | 
            -
              # # => [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]
         | 
| 41 28 | 
             
              # ```
         | 
| 42 29 | 
             
              #
         | 
| 43 30 | 
             
              # Besides each period beginning, you can also request pairs of begin/end
         | 
| 44 31 | 
             
              # of a period, either as an array of arrays, or array of ranges:
         | 
| 45 32 | 
             
              #
         | 
| 46 33 | 
             
              # ```ruby
         | 
| 47 | 
            -
              # seq = TimeMath.day.sequence(from...to)
         | 
| 48 34 | 
             
              # seq.pairs
         | 
| 49 | 
            -
              # # => [[2016-05-01  | 
| 35 | 
            +
              # # => [[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]]
         | 
| 50 36 | 
             
              # seq.ranges
         | 
| 51 | 
            -
              # # => [2016-05-01  | 
| 37 | 
            +
              # # => [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]
         | 
| 52 38 | 
             
              # ```
         | 
| 53 39 | 
             
              #
         | 
| 54 | 
            -
              # It is pretty convenient for filtering data from databases or APIs | 
| 55 | 
            -
              #  | 
| 40 | 
            +
              # It is pretty convenient for filtering data from databases or APIs: TimeMath creates list of
         | 
| 41 | 
            +
              # filtering ranges in a blink.
         | 
| 56 42 | 
             
              #
         | 
| 57 43 | 
             
              # Sequence also supports any item-updating operations in the same fashion
         | 
| 58 44 | 
             
              # {Op} does:
         | 
| 59 45 | 
             
              #
         | 
| 60 46 | 
             
              # ```ruby
         | 
| 61 | 
            -
              # seq = TimeMath.day.sequence(from...to | 
| 62 | 
            -
              # # => #<TimeMath::Sequence | 
| 47 | 
            +
              # seq = TimeMath.day.sequence(from...to).advance(:hour, 5).decrease(:min, 20)
         | 
| 48 | 
            +
              # # => #<TimeMath::Sequence day (2016-05-01 00:00:00 +0300 - 2016-05-03 00:00:00 +0300).advance(:hour, 5).decrease(:min, 20)>
         | 
| 63 49 | 
             
              # seq.to_a
         | 
| 64 | 
            -
              # # => [2016-05-01 04:40:00 +0300, 2016-05-02 04:40:00 +0300, 2016-05-03 04:40:00 +0300 | 
| 50 | 
            +
              # # => [2016-05-01 04:40:00 +0300, 2016-05-02 04:40:00 +0300, 2016-05-03 04:40:00 +0300]
         | 
| 65 51 | 
             
              # ```
         | 
| 66 52 | 
             
              #
         | 
| 67 53 | 
             
              class Sequence
         | 
| 68 | 
            -
                # Creates a sequence. Typically, it is easier to  | 
| 54 | 
            +
                # Creates a sequence. Typically, it is easier to do it with {Units::Base#sequence},
         | 
| 69 55 | 
             
                # like this:
         | 
| 70 56 | 
             
                #
         | 
| 71 57 | 
             
                # ```ruby
         | 
| @@ -76,23 +62,17 @@ module TimeMath | |
| 76 62 | 
             
                # @param range [Range] range of time-y values (Time, Date, DateTime);
         | 
| 77 63 | 
             
                #   note that range with inclusive and exclusive and will produce
         | 
| 78 64 | 
             
                #   different sequences.
         | 
| 79 | 
            -
                # @param options [Hash]
         | 
| 80 | 
            -
                # @option options [Boolean] :expand round sequence ends on creation
         | 
| 81 | 
            -
                #   (`from` is floored and `to` is ceiled);
         | 
| 82 65 | 
             
                #
         | 
| 83 | 
            -
                def initialize(unit, range | 
| 66 | 
            +
                def initialize(unit, range)
         | 
| 84 67 | 
             
                  @unit = Units.get(unit)
         | 
| 85 | 
            -
                  @from, @to | 
| 86 | 
            -
                  @options = options.dup
         | 
| 87 | 
            -
             | 
| 88 | 
            -
                  expand! if options[:expand]
         | 
| 68 | 
            +
                  @from, @to = process_range(range)
         | 
| 89 69 | 
             
                  @op = Op.new
         | 
| 90 70 | 
             
                end
         | 
| 91 71 |  | 
| 92 72 | 
             
                # @private
         | 
| 93 73 | 
             
                def initialize_copy(other)
         | 
| 94 74 | 
             
                  @unit = other.unit
         | 
| 95 | 
            -
                  @from, @to | 
| 75 | 
            +
                  @from, @to = other.from, other.to
         | 
| 96 76 | 
             
                  @op = other.op.dup
         | 
| 97 77 | 
             
                end
         | 
| 98 78 |  | 
| @@ -106,33 +86,9 @@ module TimeMath | |
| 106 86 | 
             
                def ==(other) # rubocop:disable Metrics/AbcSize
         | 
| 107 87 | 
             
                  self.class == other.class && unit == other.unit &&
         | 
| 108 88 | 
             
                    from == other.from && to == other.to &&
         | 
| 109 | 
            -
                    exclude_end? == other.exclude_end? &&
         | 
| 110 89 | 
             
                    op == other.op
         | 
| 111 90 | 
             
                end
         | 
| 112 91 |  | 
| 113 | 
            -
                # Whether sequence was created from exclude-end range (and, therefore,
         | 
| 114 | 
            -
                # will exclude `to` when converted to array).
         | 
| 115 | 
            -
                def exclude_end?
         | 
| 116 | 
            -
                  @exclude_end
         | 
| 117 | 
            -
                end
         | 
| 118 | 
            -
             | 
| 119 | 
            -
                # Expand sequence ends to nearest round unit.
         | 
| 120 | 
            -
                #
         | 
| 121 | 
            -
                # @return [self]
         | 
| 122 | 
            -
                def expand!
         | 
| 123 | 
            -
                  @from = unit.floor(from)
         | 
| 124 | 
            -
                  @to = unit.ceil(to)
         | 
| 125 | 
            -
             | 
| 126 | 
            -
                  self
         | 
| 127 | 
            -
                end
         | 
| 128 | 
            -
             | 
| 129 | 
            -
                # Creates new sequence with ends rounded to nearest unit.
         | 
| 130 | 
            -
                #
         | 
| 131 | 
            -
                # @return [Sequence]
         | 
| 132 | 
            -
                def expand
         | 
| 133 | 
            -
                  dup.expand!
         | 
| 134 | 
            -
                end
         | 
| 135 | 
            -
             | 
| 136 92 | 
             
                # @method floor!(unit, span = 1)
         | 
| 137 93 | 
             
                #   Adds {Units::Base#floor} to list of operations to apply to sequence items.
         | 
| 138 94 | 
             
                #
         | 
| @@ -239,12 +195,11 @@ module TimeMath | |
| 239 195 | 
             
                  return to_enum(:each) unless block_given?
         | 
| 240 196 |  | 
| 241 197 | 
             
                  iter = from
         | 
| 242 | 
            -
                  while iter  | 
| 198 | 
            +
                  while iter <= to
         | 
| 243 199 | 
             
                    yield(op.call(iter))
         | 
| 244 200 |  | 
| 245 201 | 
             
                    iter = unit.advance(iter)
         | 
| 246 202 | 
             
                  end
         | 
| 247 | 
            -
                  yield(op.call(to)) unless exclude_end?
         | 
| 248 203 | 
             
                end
         | 
| 249 204 |  | 
| 250 205 | 
             
                include Enumerable
         | 
| @@ -255,7 +210,7 @@ module TimeMath | |
| 255 210 | 
             
                # @return [Array<Array>]
         | 
| 256 211 | 
             
                def pairs
         | 
| 257 212 | 
             
                  seq = to_a
         | 
| 258 | 
            -
                  seq.zip(seq[1..-1]  | 
| 213 | 
            +
                  seq.zip([*seq[1..-1], unit.advance(to)])
         | 
| 259 214 | 
             
                end
         | 
| 260 215 |  | 
| 261 216 | 
             
                # Creates an array of Ranges (time unit start...time unit end) between
         | 
| @@ -269,16 +224,21 @@ module TimeMath | |
| 269 224 | 
             
                def inspect
         | 
| 270 225 | 
             
                  ops = op.inspect_operations
         | 
| 271 226 | 
             
                  ops = '.' + ops unless ops.empty?
         | 
| 272 | 
            -
                  "#<#{self.class} | 
| 227 | 
            +
                  "#<#{self.class} #{unit.name} (#{from} - #{to})#{ops}>"
         | 
| 273 228 | 
             
                end
         | 
| 274 229 |  | 
| 275 230 | 
             
                private
         | 
| 276 231 |  | 
| 232 | 
            +
                def valid_time_range?(range)
         | 
| 233 | 
            +
                  range.is_a?(Range) && Util.timey?(range.begin) && Util.timey?(range.end)
         | 
| 234 | 
            +
                end
         | 
| 235 | 
            +
             | 
| 277 236 | 
             
                def process_range(range)
         | 
| 278 | 
            -
                   | 
| 237 | 
            +
                  valid_time_range?(range) or
         | 
| 279 238 | 
             
                    raise ArgumentError, "Range of time-y values expected, #{range} got"
         | 
| 280 239 |  | 
| 281 | 
            -
                   | 
| 240 | 
            +
                  range_end = unit.floor(range.end)
         | 
| 241 | 
            +
                  [unit.floor(range.begin), range.exclude_end? ? unit.decrease(range_end) : range_end]
         | 
| 282 242 | 
             
                end
         | 
| 283 243 | 
             
              end
         | 
| 284 244 | 
             
            end
         | 
    
        data/lib/time_math/units/base.rb
    CHANGED
    
    | @@ -223,20 +223,13 @@ module TimeMath | |
| 223 223 | 
             
                  end
         | 
| 224 224 |  | 
| 225 225 | 
             
                  # Creates {Sequence} instance for producing all time units between
         | 
| 226 | 
            -
                  # from and too. See {Sequence} class documentation for  | 
| 227 | 
            -
                  # options and functionality.
         | 
| 226 | 
            +
                  # from and too. See {Sequence} class documentation for detailed functionality description.
         | 
| 228 227 | 
             
                  #
         | 
| 229 | 
            -
                  # @param  | 
| 230 | 
            -
                  # @param to [Time,Date,DateTime] upper limit of sequence;
         | 
| 231 | 
            -
                  # @param options [Hash]
         | 
| 232 | 
            -
                  # @option options [Boolean] :expand round sequence ends on creation
         | 
| 233 | 
            -
                  #   (from is floored and to is ceiled);
         | 
| 234 | 
            -
                  # @option options [Boolean] :floor sequence will be rounding'ing all
         | 
| 235 | 
            -
                  #   the intermediate values.
         | 
| 228 | 
            +
                  # @param range [Range<Time,Date,DateTime>] start and end of sequence.
         | 
| 236 229 | 
             
                  #
         | 
| 237 230 | 
             
                  # @return [Sequence]
         | 
| 238 | 
            -
                  def sequence(range | 
| 239 | 
            -
                    TimeMath::Sequence.new(name, range | 
| 231 | 
            +
                  def sequence(range)
         | 
| 232 | 
            +
                    TimeMath::Sequence.new(name, range)
         | 
| 240 233 | 
             
                  end
         | 
| 241 234 |  | 
| 242 235 | 
             
                  # Converts input timestamps list to regular list of timestamps
         | 
    
        data/lib/time_math/version.rb
    CHANGED
    
    
    
        data/time_math2.gemspec
    CHANGED
    
    
    
        metadata
    CHANGED
    
    | @@ -1,14 +1,14 @@ | |
| 1 1 | 
             
            --- !ruby/object:Gem::Specification
         | 
| 2 2 | 
             
            name: time_math2
         | 
| 3 3 | 
             
            version: !ruby/object:Gem::Version
         | 
| 4 | 
            -
              version: 0.0 | 
| 4 | 
            +
              version: 0.1.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - Victor Shepelev
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2017-07- | 
| 11 | 
            +
            date: 2017-07-30 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: rubocop
         | 
| @@ -165,7 +165,7 @@ required_ruby_version: !ruby/object:Gem::Requirement | |
| 165 165 | 
             
              requirements:
         | 
| 166 166 | 
             
              - - ">="
         | 
| 167 167 | 
             
                - !ruby/object:Gem::Version
         | 
| 168 | 
            -
                  version:  | 
| 168 | 
            +
                  version: 2.1.0
         | 
| 169 169 | 
             
            required_rubygems_version: !ruby/object:Gem::Requirement
         | 
| 170 170 | 
             
              requirements:
         | 
| 171 171 | 
             
              - - ">="
         |