Module: TimeExt::Iterations

Included in:
Time
Defined in:
lib/time_ext/iterations.rb

Overview

Allows you to iterate over Time objects with #each and other methods almost as if it was an Array or Hash.

Instance Method Summary collapse

Instance Method Details

#beginning_of_each(unit, options = {}, &block) ⇒ Object

Executes passed block for each “unit” of time specified, with a new time object set to the beginning of “unit” for each interval passed to the block.



70
71
72
# File 'lib/time_ext/iterations.rb', line 70

def beginning_of_each(unit, options = {}, &block)
  iterate(unit, options.merge(:map_result => false, :beginning_of => true), &block)
end

#each(unit, options = {}, &block) ⇒ Object

Executes passed block for each “unit” of time specified, with a new time object for each interval passed to the block.



65
66
67
# File 'lib/time_ext/iterations.rb', line 65

def each(unit, options = {}, &block)
  iterate(unit, options.merge(:map_result => false), &block)
end

#from(time, &block) ⇒ Object

Used together with #each and other interation methods to specify start of iteration, and end will be current object.



46
47
48
49
50
51
52
53
54
# File 'lib/time_ext/iterations.rb', line 46

def from(time, &block)
  time = time.to_time if time.is_a?(::Date)
  method, args = @method_chain.pop if block_given?
  if !method.nil?
    time.until(self).send(method, *args, &block)
  else
    time.until(self)
  end
end

#iterate(unit, options = {}, &block) ⇒ Object

Used by #each, #map_each and similar methods to iterate over ranges of time.



6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
# File 'lib/time_ext/iterations.rb', line 6

def iterate(unit, options = {}, &block)
  options.reverse_merge!(:map_result => false, :beginning_of => false, :include_start => false, :include_end => true)
  if block_given?
    units = [:year, :month, :day, :hour, :min, :sec, :usec]
    parent_unit = units[units.index(unit)-1]
    if @of_the.nil?
      time = self.clone
      @until ||= (!parent_unit.nil?) ? self.send("#{parent_unit}s_since", 1) : self.send("#{unit}s_since", 1)
    else
      time = self.beginning_of(@of_the)
      @until = self.next(@of_the).beginning_of(@of_the)
      options.merge!(:beginning_of => true, :include_start => true, :include_end => false)
    end
    direction = (self < @until) ? :f : :b
    succ_method = (direction == :f) ? "next_#{unit}" : "prev_#{unit}"
    time = time.beginning_of(unit) if options[:beginning_of]
    time = time.send(succ_method) if !options[:include_start]
    @until = @until.prev(unit).end_of(unit) if !options[:include_end]
    results = []
    while (direction == :f && time <= @until) || (direction == :b && time >= @until)
      options[:map_result] ? results << yield(time) : yield(time)
      time = time.send(succ_method)
    end
    options[:map_result] ? results : self
  else
    add_to_chain(:iterate, unit, options)
    self
  end
end

#map_beginning_of_each(unit, options = {}, &block) ⇒ Object

Executes passed block for each “unit” of time specified, returning an array with the return values from passed block. Additionally the time object passed into the block is set to the beginning of specified “unit”.



80
81
82
# File 'lib/time_ext/iterations.rb', line 80

def map_beginning_of_each(unit, options = {}, &block)
  iterate(unit, options.merge(:map_result => true, :beginning_of => true), &block)
end

#map_each(unit, options = {}, &block) ⇒ Object

Executes passed block for each “unit” of time specified, returning an array with the return values from the passed block.



75
76
77
# File 'lib/time_ext/iterations.rb', line 75

def map_each(unit, options = {}, &block)
  iterate(unit, options.merge(:map_result => true), &block)
end

#of_the(unit, &block) ⇒ Object Also known as: of

Let’s you iterate over every unit specified in the #each or #map call for the specified unit.



57
58
59
60
61
# File 'lib/time_ext/iterations.rb', line 57

def of_the(unit, &block)
  @of_the = unit
  return call_chain(block) if block_given?
  self
end

#until(time, &block) ⇒ Object Also known as: till

Used togeter with #each and other iteration methods to specify end of interation.



37
38
39
40
41
42
# File 'lib/time_ext/iterations.rb', line 37

def until(time, &block)
  time = time.to_time if time.is_a?(::Date)
  @until = time
  return call_chain(block) if block_given?
  self
end