Class: Period

Inherits:
Object
  • Object
show all
Defined in:
lib/periodicity/period.rb

Constant Summary collapse

DAY_PERIODS =
{
  "morning" => 9,
  "noon" => 12,
  "afternoon" => 19,
  "midnight" => 0
}

Instance Method Summary collapse

Constructor Details

#initialize(last_run = nil) ⇒ Period

Initializes a new Period object with the last_run used for the next_run calculations

A Period object needs at least an every and time period (minutes, hours etc) to functions properly:
  Period.new.every.day
  Period.new(2.hours.ago).every(4).hours

If last_run is nil, next_run will always return Time.now


18
19
20
21
# File 'lib/periodicity/period.rb', line 18

def initialize(last_run = nil)
  @last_run = last_run
  @at = 0
end

Instance Method Details

#at(time) ⇒ Object

Sets a specific “sub-time” for the next_run:

  every(2).hours.at(15) # means "every 2 hours at the first quarter of each" e.g. 12:15, 14:15, 16:15

Specific time within a day is also supported:
  every(3).days.at('5:30') # means "every 3 days at 05:30"

<b>NOTE 1:</b> when using at and from, to limits together the limits *always* calculate at 0 "sub-time":
  every(2).hours.at(15).from(12).to(16) # will return 12:15, 14:15 but not 16:15 because the to limit ends at 16:00

<b>NOTE 2:</b> when using minute precision (5:30) but instead of every.day the interval is in another period, the minutes will be discarded.
  every.hour.at('5:30') # means "every hour at :05" (e.g. 12:05, 13:05, 14:05)


121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
# File 'lib/periodicity/period.rb', line 121

def at(time)
  unless time.is_a?(Integer)
    time = case time.to_s
    when /^\d+:00$/
      time[/^\d+/].to_i
    when /^\d+:\d{2}$/
      @min_at = time.split(/:/)[1].to_i
      time.split(/:/)[0].to_i
    when /^(noon|afternoon|midnight|morning)$/
      DAY_PERIODS[time.to_s]
    else
      time.to_i
    end
  end
  
  @at = time
  return self
end

#daysObject Also known as: day

Sets the scope to one day so that every(4).days means “every 4 days”



49
50
51
52
53
54
# File 'lib/periodicity/period.rb', line 49

def days
  @scope = 1.days
  reset_on_base 24
  
  return self
end

#every(int = 1) ⇒ Object

Sets the interval at which the runs should be calculated:

every.day
every(20).minutes
every(2).hours


30
31
32
33
# File 'lib/periodicity/period.rb', line 30

def every(int = 1)
  @interval = int
  return self
end

#from(time) ⇒ Object

Sets the from limit based on the scope:

every(2).hours.from(8) # means "every 2 hours beginning from 8:00"


94
95
96
97
# File 'lib/periodicity/period.rb', line 94

def from(time)
  @from = time
  return self
end

#hoursObject Also known as: hour

Sets the scope to one hour so that every(6).hours means “every 6 hours”



60
61
62
63
64
65
# File 'lib/periodicity/period.rb', line 60

def hours
  @scope = 1.hour
  reset_on_base 60
  
  return self
end

#minutesObject Also known as: minute

Sets the scope to one minute so that every(20).minutes means “every 20 minutes”



71
72
73
74
75
76
# File 'lib/periodicity/period.rb', line 71

def minutes
  @scope = 1.minute
  reset_on_base 60
  
  return self
end

#next_runObject

This return a Time object for the next calculated time:

  now = "Aug 05 14:40:23 2009".to_time
  Period.new(now).every(2).hours.next_run # => Wed Aug 05 16:00:00 UTC 2009

Note that it rounds all "sub-time" to 0 by default (can be overriden with at)


147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
# File 'lib/periodicity/period.rb', line 147

def next_run
  return Time.now unless @last_run
  
  @next_run = @last_run
  
  if @scope and @interval
    @next_run += @interval * @scope
    
    calc_precision
    
    calc_limits
  else
    raise 'No proper period specified'
  end
  
  return @next_run
end

#secondsObject Also known as: second

Sets the scope to one second so that every(5).seconds means “every 5 seconds”



82
83
84
85
86
87
# File 'lib/periodicity/period.rb', line 82

def seconds
  @scope = 1.second
  reset_on_base false
  
  return self
end

#to(time) ⇒ Object

Sets the to limit based on the scope:

every(2).hours.to(12) # means "every 2 hours until 12:00"


103
104
105
106
# File 'lib/periodicity/period.rb', line 103

def to(time)
  @to = time
  return self
end

#weeksObject Also known as: week

Sets the scope to one week so that every(2).weeks means “every 2 weeks”



38
39
40
41
42
43
# File 'lib/periodicity/period.rb', line 38

def weeks
  @scope = 1.week
  reset_on_base 7
  
  return self
end