Class: Whedon::Schedule
- Inherits:
-
Object
- Object
- Whedon::Schedule
- Defined in:
- lib/whedon/schedule.rb
Overview
A ‘cron line’ is a line in the sense of a crontab (man 5 crontab) file line.
Constant Summary collapse
- DAY_S =
24 * 3600
- WEEK_S =
7 * DAY_S
Instance Attribute Summary collapse
-
#days ⇒ Object
readonly
Returns the value of attribute days.
-
#hours ⇒ Object
readonly
Returns the value of attribute hours.
-
#minutes ⇒ Object
readonly
Returns the value of attribute minutes.
-
#months ⇒ Object
readonly
Returns the value of attribute months.
-
#original ⇒ Object
readonly
The string used for creating this cronline instance.
-
#raise_error_on_duplicate ⇒ Object
Returns the value of attribute raise_error_on_duplicate.
-
#seconds ⇒ Object
readonly
Returns the value of attribute seconds.
-
#timezone ⇒ Object
readonly
Returns the value of attribute timezone.
-
#weekdays ⇒ Object
readonly
Returns the value of attribute weekdays.
Instance Method Summary collapse
-
#initialize(line) ⇒ Schedule
constructor
A new instance of Schedule.
-
#matches?(time) ⇒ Boolean
Returns true if the given time matches this cron line.
-
#next_time(now = Time.now) ⇒ Object
(also: #next)
Returns the next time that this cron line is supposed to ‘fire’.
- #now?(time = Time.now) ⇒ Boolean
-
#previous_time(now = Time.now) ⇒ Object
(also: #previous, #last)
Returns the previous the cronline matched.
-
#to_array ⇒ Object
(also: #to_a)
Returns an array of 6 arrays (seconds, minutes, hours, days, months, weekdays).
Constructor Details
#initialize(line) ⇒ Schedule
Returns a new instance of Schedule.
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/whedon/schedule.rb', line 56 def initialize(line) super() @original = line items = line.split @timezone = (TZInfo::Timezone.get(items.last) rescue nil) items.pop if @timezone raise ParseError.new( "not a valid cronline : '#{line}'" ) unless items.length == 5 or items.length == 6 offset = items.length - 5 @seconds = offset == 1 ? parse_item(items[0], 0, 59) : [ 0 ] @minutes = parse_item(items[0 + offset], 0, 59) @hours = parse_item(items[1 + offset], 0, 24) @days = parse_item(items[2 + offset], 1, 31) @months = parse_item(items[3 + offset], 1, 12) @weekdays, @monthdays = parse_weekdays(items[4 + offset]) [ @seconds, @minutes, @hours, @months ].each do |es| raise ParseError.new( "invalid cronline: '#{line}'" ) if es && es.find { |e| ! e.is_a?(Fixnum) } end end |
Instance Attribute Details
#days ⇒ Object (readonly)
Returns the value of attribute days.
48 49 50 |
# File 'lib/whedon/schedule.rb', line 48 def days @days end |
#hours ⇒ Object (readonly)
Returns the value of attribute hours.
47 48 49 |
# File 'lib/whedon/schedule.rb', line 47 def hours @hours end |
#minutes ⇒ Object (readonly)
Returns the value of attribute minutes.
46 47 48 |
# File 'lib/whedon/schedule.rb', line 46 def minutes @minutes end |
#months ⇒ Object (readonly)
Returns the value of attribute months.
49 50 51 |
# File 'lib/whedon/schedule.rb', line 49 def months @months end |
#original ⇒ Object (readonly)
The string used for creating this cronline instance.
43 44 45 |
# File 'lib/whedon/schedule.rb', line 43 def original @original end |
#raise_error_on_duplicate ⇒ Object
Returns the value of attribute raise_error_on_duplicate.
54 55 56 |
# File 'lib/whedon/schedule.rb', line 54 def raise_error_on_duplicate @raise_error_on_duplicate end |
#seconds ⇒ Object (readonly)
Returns the value of attribute seconds.
45 46 47 |
# File 'lib/whedon/schedule.rb', line 45 def seconds @seconds end |
#timezone ⇒ Object (readonly)
Returns the value of attribute timezone.
52 53 54 |
# File 'lib/whedon/schedule.rb', line 52 def timezone @timezone end |
#weekdays ⇒ Object (readonly)
Returns the value of attribute weekdays.
50 51 52 |
# File 'lib/whedon/schedule.rb', line 50 def weekdays @weekdays end |
Instance Method Details
#matches?(time) ⇒ Boolean
Returns true if the given time matches this cron line.
90 91 92 93 94 95 96 97 98 99 |
# File 'lib/whedon/schedule.rb', line 90 def matches?(time) time = as_time(time) return false unless sub_match?(time, :sec, @seconds) return false unless sub_match?(time, :min, @minutes) return false unless sub_match?(time, :hour, @hours) return false unless date_match?(time) true end |
#next_time(now = Time.now) ⇒ Object Also known as: next
Returns the next time that this cron line is supposed to ‘fire’
This is raw, 3 secs to iterate over 1 year on my macbook :( brutal. (Well, I was wrong, takes 0.001 sec on 1.8.7 and 1.9.1)
This method accepts an optional Time parameter. It’s the starting point for the ‘search’. By default, it’s Time.now
Note that the time instance returned will be in the same time zone that the given start point Time (thus a result in the local time zone will be passed if no start time is specified (search start time set to Time.now))
Whedon::CronLine.new('30 7 * * *').next_time(
Time.mktime(2008, 10, 24, 7, 29))
#=> Fri Oct 24 07:30:00 -0500 2008
Whedon::CronLine.new('30 7 * * *').next_time(
Time.utc(2008, 10, 24, 7, 29))
#=> Fri Oct 24 07:30:00 UTC 2008
Whedon::CronLine.new('30 7 * * *').next_time(
Time.utc(2008, 10, 24, 7, 29)).localtime
#=> Fri Oct 24 02:30:00 -0500 2008
(Thanks to K Liu for the note and the examples)
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 |
# File 'lib/whedon/schedule.rb', line 132 def next_time(now=Time.now) time = as_time(now) time = time - time.usec * 1e-6 + 1 # small adjustment before starting loop do unless date_match?(time) time += (24 - time.hour) * 3600 - time.min * 60 - time.sec; next end unless sub_match?(time, :hour, @hours) time += (60 - time.min) * 60 - time.sec; next end unless sub_match?(time, :min, @minutes) time += 60 - time.sec; next end unless sub_match?(time, :sec, @seconds) time += 1; next end break end if @timezone time = @timezone.local_to_utc(time) time = time.getlocal unless now.utc? end time end |
#now?(time = Time.now) ⇒ Boolean
101 102 103 |
# File 'lib/whedon/schedule.rb', line 101 def now?(time=Time.now) matches?(time) end |
#previous_time(now = Time.now) ⇒ Object Also known as: previous, last
Returns the previous the cronline matched. It’s like next_time, but for the past.
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 |
# File 'lib/whedon/schedule.rb', line 168 def previous_time(now=Time.now) # looks back by slices of two hours, # # finds for '* * * * sun', '* * 13 * *' and '0 12 13 * *' # starting 1970, 1, 1 in 1.8 to 2 seconds (says Rspec) start = current = now - 2 * 3600 result = nil loop do nex = next_time(current) return (result ? result : previous_time(start)) if nex > now result = current = nex end # never reached end |
#to_array ⇒ Object Also known as: to_a
Returns an array of 6 arrays (seconds, minutes, hours, days, months, weekdays). This method is used by the cronline unit tests.
193 194 195 196 197 198 199 200 201 202 203 204 205 |
# File 'lib/whedon/schedule.rb', line 193 def to_array [ @seconds, @minutes, @hours, @days, @months, @weekdays, @monthdays, @timezone ? @timezone.name : nil ] end |