Class: Recurring::Schedule
- Inherits:
-
Object
- Object
- Recurring::Schedule
- Defined in:
- lib/schedule.rb
Overview
Initialize a Schedule object with the proper options to calculate occurances in that schedule. Schedule#new take a hash of options :unit, :frequency, :anchor, :weeks, :monthdays, :weekdays, :times
Yearly
- Every two years from an anchor time
-
Recurring::Schedule.new :unit => 'years', :frequency => 2, :anchor => Time.utc(2006,4,15,10,30)
- Every year in February and May on the 1st and 15th
-
Recurring::Schedule.new :unit => 'years', :months => ['feb', 'may'], :monthdays => [1,15]
- Every year in February and May on the 1st and 15th
-
Recurring::Schedule.new :unit => 'years', :months => ['feb', 'may'], :monthdays => [1,15]
Monthly
- Every two months from an anchor time
-
Recurring::Schedule.new :unit => 'months', :frequency => 2, :anchor => Time.utc(2006,4,15,10,30)
- The first and fifteenth of every month
-
Recurring::Schedule.new :unit => 'months', :monthdays => [1,15]
- The first and eighteenth of every third month
-
Recurring::Schedule.new :unit => 'months', :frequency => 3, :anchor => Time.utc(2006,4,15,10,30), :monthdays => [10,18]
- The third Monday of every month at 6:30pm
-
Recurring::Schedule.new :unit => 'months', :weeks => 3, :weekdays => :monday, :times => '6:30pm'
Weekly
- Monday, Wednesday, and Friday of every week
-
Recurring::Schedule.new :unit => 'weeks', :weekdays => %w{monday weds friday}
- Every week at the same time on the same day of the week as the anchor (Weds at 5:30pm)
-
Recurring::Schedule.new :unit => 'weeks', :anchor => Time.utc(2006,12,6,17,30)
- Equivalently, Every Wednesday at 5:30
-
Recurring::Schedule.new :unit => 'weeks', :weekdays => 'weds', :times => '5:30pm'
Daily
- Everyday at the time of the anchor
-
Recurring::Schedule.new :unit => 'days', :anchor => Time.utc(2006,11,1,10,15,22)
- Everyday at 7am and 5:45:20pm
-
Recurring::Schedule.new :unit => 'days', :times => '7am 5:45:20pm'
Hourly
- Every hour at 15 minutes, 30 minutes, and 45 minutes and 30 seconds
-
Recurring::Schedule.new :unit => 'hours', :times => '0:15 4:30 0:45:30'
- Offset every 2 hours from the anchor
-
Recurring::Schedule.new :unit => 'hours', :anchor => Time.utc(2001,5,15,11,17)
Minutely
- Every five minutes offset from the anchor
-
Recurring::Schedule.new :unit => 'minutes', :frequency => 5, :anchor => Time.utc(2006,9,1,10,30)
- Every minute at second 15
-
Recurring::Schedule.new :unit => 'minutes', :times => '0:0:15'
See the specs using “rake spec” for even more examples.
Instance Attribute Summary collapse
-
#anchor ⇒ Object
readonly
Returns the value of attribute anchor.
-
#frequency ⇒ Object
readonly
Returns the value of attribute frequency.
-
#monthdays ⇒ Object
readonly
Returns the value of attribute monthdays.
-
#months ⇒ Object
readonly
Returns the value of attribute months.
-
#times ⇒ Object
readonly
Returns the value of attribute times.
-
#unit ⇒ Object
readonly
Returns the value of attribute unit.
-
#weekdays ⇒ Object
readonly
Returns the value of attribute weekdays.
-
#weeks ⇒ Object
readonly
Returns the value of attribute weeks.
Instance Method Summary collapse
-
#==(other) ⇒ Object
Two Schedules are equal if they have the same attributes.
-
#find_in_range(*args) ⇒ Object
Takes a range which responds to
first
andlast
, returning Time objects. -
#find_next(date) ⇒ Object
Starts from the argument time, and returns the next included time.
-
#find_previous(date) ⇒ Object
Starts from the argument time, and works backwards until it hits a time that is included.
-
#include?(date) ⇒ Boolean
Returns true or false depending on whether or not the time is included in the schedule.
-
#initialize(options) ⇒ Schedule
constructor
Options hash has keys
:unit, :frequency, :anchor, :weeks, :monthdays, :weekdays, :times
* valid values for :unit areyears, months, weeks, days, hours, minutes
* :frequency defaults to 1 * :anchor is required if the frequency is other than one * :weeks alongside :weekdays is used to specify the nth instance of a weekday in a month. - #timeout!(time) ⇒ Object
Constructor Details
#initialize(options) ⇒ Schedule
Options hash has keys :unit, :frequency, :anchor, :weeks, :monthdays, :weekdays, :times
-
valid values for :unit are
years, months, weeks, days, hours, minutes
-
:frequency defaults to 1
-
:anchor is required if the frequency is other than one
-
:weeks alongside :weekdays is used to specify the nth instance of a weekday in a month.
-
:weekdays takes an array of strings like
%w{monday weds friday}
-
:monthdays takes an array of days of the month, eg.
[1,7,15]
-
:times takes a string with a simple format.
"4pm 5:15pm 6:45:30pm"
63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 |
# File 'lib/schedule.rb', line 63 def initialize raise ArgumentError, 'specify a valid unit' unless [:unit] && %w{years months weeks days hours minutes}.include?([:unit]) raise ArgumentError, 'frequency > 1 requires an anchor Time' if [:frequency] && [:frequency] != 1 && ![:anchor] @unit = [:unit].to_sym raise ArgumentError, 'weekdays are required with the weeks param, if there are times params' if @unit == :weeks && [:times] && ![:weekdays] @frequency = [:frequency] || 1 @anchor = [:anchor] @times = parse_times [:times] if [:months] @month_args = Array([:months]).collect{|d|d.to_s.downcase.to_sym} raise ArgumentError, 'provide valid months' unless @month_args.all?{|m|ordinal_month(m)} @months = @month_args.collect{|m|ordinal_month(m)} end @weeks = Array([:weeks]).collect{|n|n.to_i} if [:weeks] if [:weekdays] @weekdays_args = Array([:weekdays]).collect{|d|d.to_s.downcase.to_sym} raise ArgumentError, 'provide valid weekdays' unless @weekdays_args.all?{|w|ordinal_weekday(w)} @weekdays = @weekdays_args.collect{|w|ordinal_weekday(w)} end @monthdays = Array([:monthdays]).collect{|n|n.to_i} if [:monthdays] @anchor_multiple = [:times].nil? && [:weeks].nil? && [:weekdays].nil? && [:monthdays].nil? end |
Instance Attribute Details
#anchor ⇒ Object (readonly)
Returns the value of attribute anchor.
53 54 55 |
# File 'lib/schedule.rb', line 53 def anchor @anchor end |
#frequency ⇒ Object (readonly)
Returns the value of attribute frequency.
53 54 55 |
# File 'lib/schedule.rb', line 53 def frequency @frequency end |
#monthdays ⇒ Object (readonly)
Returns the value of attribute monthdays.
53 54 55 |
# File 'lib/schedule.rb', line 53 def monthdays @monthdays end |
#months ⇒ Object (readonly)
Returns the value of attribute months.
53 54 55 |
# File 'lib/schedule.rb', line 53 def months @months end |
#times ⇒ Object (readonly)
Returns the value of attribute times.
53 54 55 |
# File 'lib/schedule.rb', line 53 def times @times end |
#unit ⇒ Object (readonly)
Returns the value of attribute unit.
53 54 55 |
# File 'lib/schedule.rb', line 53 def unit @unit end |
#weekdays ⇒ Object (readonly)
Returns the value of attribute weekdays.
53 54 55 |
# File 'lib/schedule.rb', line 53 def weekdays @weekdays end |
#weeks ⇒ Object (readonly)
Returns the value of attribute weeks.
53 54 55 |
# File 'lib/schedule.rb', line 53 def weeks @weeks end |
Instance Method Details
#==(other) ⇒ Object
Two Schedules are equal if they have the same attributes.
172 173 174 175 176 177 |
# File 'lib/schedule.rb', line 172 def == other return false unless self.class == other.class [:unit, :frequency, :anchor, :weeks, :monthdays, :weekdays, :times].all? do |attribute| self.send(attribute) == other.send(attribute) end end |
#find_in_range(*args) ⇒ Object
Takes a range which responds to first
and last
, returning Time objects. The arguments need only to be duck-type compatible with Time#year, #month, #day, #hour, #min, #sec, #wday etc.
rs.find_in_range(Time.now, Time.now+24*60*60)
or
range = (Time.now..Time.now+24*60*60)
rs.find_in_range(range)
146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 |
# File 'lib/schedule.rb', line 146 def find_in_range *args if args[0].respond_to?(:first) && args[0].respond_to?(:last) t_start = args[0].first t_end = args[0].last else t_start = args[0] t_end = args[1] end opts = args.last if args.last.respond_to?(:keys) if opts limit = opts[:limit] end result = [] count = 1 loop do rnext = find_next t_start break if count > limit if limit break if rnext > t_end result << rnext t_start = rnext + 1 count += 1 end result end |
#find_next(date) ⇒ Object
Starts from the argument time, and returns the next included time. Returns the argument if it is included in the schedule.
120 121 122 123 124 125 126 |
# File 'lib/schedule.rb', line 120 def find_next date loop do return date if include?(date) #puts "#{@resolution} : #{date}" date = beginning_of_next @resolution, date end end |
#find_previous(date) ⇒ Object
Starts from the argument time, and works backwards until it hits a time that is included
129 130 131 132 133 134 135 |
# File 'lib/schedule.rb', line 129 def find_previous date loop do return date if include?(date) #puts "#{@resolution} : #{date}" date = end_of_previous @resolution, date end end |
#include?(date) ⇒ Boolean
Returns true or false depending on whether or not the time is included in the schedule.
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 |
# File 'lib/schedule.rb', line 97 def include? date @resolution = nil return true if check_anchor? && date == @anchor return mismatch(:year) unless year_matches?(date) if @unit == :years return mismatch(:month) unless month_matches?(date) if [:months, :years].include?(@unit) return mismatch(:week) unless week_matches?(date) if [:years, :months, :weeks].include?(@unit) if [:years, :months, :weeks, :days].include?(@unit) return mismatch(:day) unless day_matches?(date) return mismatch(:time) unless time_matches?(date) end if @unit == :hours return mismatch(:hour) unless hour_matches?(date) return mismatch(:sub_hour) unless sub_hour_matches?(date) end if @unit == :minutes return mismatch(:minute) unless minute_matches?(date) return mismatch(:second) unless second_matches?(date) end @resolution = nil true end |
#timeout!(time) ⇒ Object
92 93 94 |
# File 'lib/schedule.rb', line 92 def timeout! time @timeout = time end |