Parent

Rufus::CronLine

A ‘cron line’ is a line in the sense of a crontab (man 5 crontab) file line.

Constants

WDS

Attributes

original[R]

The string used for creating this cronline instance.

seconds[R]
minutes[R]
hours[R]
days[R]
months[R]
weekdays[R]
timezone[R]

Public Class Methods

new(line) click to toggle source
    # File lib/rufus/sc/cronline.rb, line 48
48:     def initialize(line)
49: 
50:       super()
51: 
52:       @original = line
53: 
54:       items = line.split
55: 
56:       @timezone = (TZInfo::Timezone.get(items.last) rescue nil)
57:       items.pop if @timezone
58: 
59:       raise ArgumentError.new(
60:         "not a valid cronline : '#{line}'"
61:       ) unless items.length == 5 or items.length == 6
62: 
63:       offset = items.length - 5
64: 
65:       @seconds = offset == 1 ? parse_item(items[0], 0, 59) : [ 0 ]
66:       @minutes = parse_item(items[0 + offset], 0, 59)
67:       @hours = parse_item(items[1 + offset], 0, 24)
68:       @days = parse_item(items[2 + offset], 1, 31)
69:       @months = parse_item(items[3 + offset], 1, 12)
70:       @weekdays = parse_weekdays(items[4 + offset])
71:     end

Public Instance Methods

matches?(time) click to toggle source

Returns true if the given time matches this cron line.

    # File lib/rufus/sc/cronline.rb, line 75
75:     def matches?(time)
76: 
77:       time = Time.at(time) unless time.kind_of?(Time)
78: 
79:       time = @timezone.utc_to_local(time.getutc) if @timezone
80: 
81:       return false unless sub_match?(time.sec, @seconds)
82:       return false unless sub_match?(time.min, @minutes)
83:       return false unless sub_match?(time.hour, @hours)
84:       return false unless sub_match?(time.day, @days)
85:       return false unless sub_match?(time.month, @months)
86:       return false unless sub_match?(time.wday, @weekdays)
87:       true
88:     end
next_time(now=Time.now) click to toggle source

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))

  Rufus::CronLine.new('30 7 * * *').next_time(
    Time.mktime(2008, 10, 24, 7, 29))
  #=> Fri Oct 24 07:30:00 -0500 2008

  Rufus::CronLine.new('30 7 * * *').next_time(
    Time.utc(2008, 10, 24, 7, 29))
  #=> Fri Oct 24 07:30:00 UTC 2008

  Rufus::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)

     # File lib/rufus/sc/cronline.rb, line 117
117:     def next_time(now=Time.now)
118: 
119:       time = @timezone ? @timezone.utc_to_local(now.getutc) : now
120: 
121:       time = time - time.usec * 1e-6 + 1
122:         # little adjustment before starting
123: 
124:       loop do
125: 
126:         unless date_match?(time)
127:           time += (24 - time.hour) * 3600 - time.min * 60 - time.sec
128:           next
129:         end
130:         unless sub_match?(time.hour, @hours)
131:           time += (60 - time.min) * 60 - time.sec
132:           next
133:         end
134:         unless sub_match?(time.min, @minutes)
135:           time += 60 - time.sec
136:           next
137:         end
138:         unless sub_match?(time.sec, @seconds)
139:           time += 1
140:           next
141:         end
142: 
143:         break
144:       end
145: 
146:       if @timezone
147:         time = @timezone.local_to_utc(time)
148:         time = time.getlocal unless now.utc?
149:       end
150: 
151:       time
152:     end
to_array() click to toggle source

Returns an array of 6 arrays (seconds, minutes, hours, days, months, weekdays). This method is used by the cronline unit tests.

     # File lib/rufus/sc/cronline.rb, line 158
158:     def to_array
159: 
160:       [
161:         @seconds,
162:         @minutes,
163:         @hours,
164:         @days,
165:         @months,
166:         @weekdays,
167:         @timezone ? @timezone.name : nil
168:       ]
169:     end

Private Instance Methods

date_match?(date) click to toggle source
     # File lib/rufus/sc/cronline.rb, line 258
258:     def date_match?(date)
259: 
260:       return false unless sub_match?(date.day, @days)
261:       return false unless sub_match?(date.month, @months)
262:       return false unless sub_match?(date.wday, @weekdays)
263:       true
264:     end
parse_item(item, min, max) click to toggle source
     # File lib/rufus/sc/cronline.rb, line 189
189:     def parse_item(item, min, max)
190: 
191:       return nil if item == '*'
192:       return parse_list(item, min, max) if item.index(',')
193:       return parse_range(item, min, max) if item.index('*') or item.index('-')
194: 
195:       i = Integer(item)
196: 
197:       i = min if i < min
198:       i = max if i > max
199: 
200:       [ i ]
201:     end
parse_list(item, min, max) click to toggle source
     # File lib/rufus/sc/cronline.rb, line 203
203:     def parse_list(item, min, max)
204: 
205:       item.split(',').inject([]) { |r, i|
206:         r.push(parse_range(i, min, max))
207:       }.flatten
208:     end
parse_range(item, min, max) click to toggle source
     # File lib/rufus/sc/cronline.rb, line 210
210:     def parse_range(item, min, max)
211: 
212:       i = item.index('-')
213:       j = item.index('/')
214: 
215:       return item.to_i if (not i and not j)
216: 
217:       inc = j ? Integer(item[j+1..1]) : 1
218: 
219:       istart = 1
220:       iend = 1
221: 
222:       if i
223: 
224:         istart = Integer(item[0..i - 1])
225: 
226:         if j
227:           iend = Integer(item[i + 1..j])
228:         else
229:           iend = Integer(item[i + 1..1])
230:         end
231: 
232:       else # case */x
233: 
234:         istart = min
235:         iend = max
236:       end
237: 
238:       istart = min if istart < min
239:       iend = max if iend > max
240: 
241:       result = []
242: 
243:       value = istart
244:       loop do
245:         result << value
246:         value = value + inc
247:         break if value > iend
248:       end
249: 
250:       result
251:     end
parse_weekdays(item) click to toggle source

used by parse_weekday()

     # File lib/rufus/sc/cronline.rb, line 176
176:     def parse_weekdays(item)
177: 
178:       item = item.downcase
179: 
180:       WDS.each_with_index { |day, index| item = item.gsub(day, index.to_s) }
181: 
182:       r = parse_item(item, 0, 7)
183: 
184:       r.is_a?(Array) ?
185:         r.collect { |e| e == 7 ? 0 : e }.uniq :
186:         r
187:     end
sub_match?(value, values) click to toggle source
     # File lib/rufus/sc/cronline.rb, line 253
253:     def sub_match?(value, values)
254: 
255:       values.nil? || values.include?(value)
256:     end

Disabled; run with --debug to generate this.

[Validate]

Generated with the Darkfish Rdoc Generator 1.1.6.