Methods
- cron_expr=
- day=
- day_restricted?
- fire_time_after
- hour=
- min=
- month=
- new
- sec=
- wday=
- wday_restricted?
- year=
Constants
| LeapYearMonthDays | = | [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] |
| CommonYearMonthDays | = | [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] |
Attributes
| [R] | cron_expr | |
| [R] | day | |
| [R] | hour | |
| [R] | min | |
| [R] | month | |
| [R] | sec | |
| [R] | wday | |
| [R] | year |
Public Class methods
[ show source ]
# File server/cron_trigger.rb, line 6 6: def initialize(expr) 7: self.cron_expr = expr 8: end
Public Instance methods
[ show source ]
# File server/cron_trigger.rb, line 10
10: def cron_expr=(expr)
11: @cron_expr = expr
12: self.sec, self.min, self.hour, self.day, self.month, self.wday, self.year = @cron_expr.split(' ')
13: # puts inspect
14: end
[ show source ]
# File server/cron_trigger.rb, line 184
184: def day=(day)
185: @day = parse_part(day, 1 .. 31)
186: end
[ show source ]
# File server/cron_trigger.rb, line 163
163: def day_restricted?
164: return !@day.eql?(1..31)
165: end
[ show source ]
# File server/cron_trigger.rb, line 16
16: def fire_time_after(time)
17: sec, min, hour, day, month, year, wday, yday, isdst, zone = time.to_a
18:
19: loop do
20: # year
21: unless @year.nil? or @year.include?(year)
22: return nil if year > @year.max
23: year = @year.detect do |y| y > year end # next allowable year
24: end
25:
26: # month
27: unless @month.include?(month)
28: # next allowable month
29: next_month = @month.detect(lambda { @month.min }) do |m| m > month end
30: # reset everything lower
31: day, hour, min, sec = @day.min, @hour.min, @min.min, @sec.min
32: # carry case
33: if next_month < month
34: month = next_month
35: year += 1
36: retry
37: end
38: month = next_month
39: end
40:
41: # according to crontab(5):
42: # Note: The day of a command’s execution can be specified by two fields — day of month, and day of week.
43: # If both fields are restricted (i.e., aren’t *), the command will be run when either
44: # field matches the current time. For example, ‘‘30 4 1,15 * 5’’ would cause a command to be
45: # run at 4:30 am on the 1st and 15th of each month, plus every Friday.
46: if !day_restricted? and wday_restricted?
47: # unrestricted day, restricted wday. go by wday
48: unless @wday.include?(wday)
49: next_wday = @wday.detect(lambda { @wday.min }) do |w| w > wday end
50: hour, min, sec = @hour.min, @min.min, @sec.min
51: if next_wday < wday
52: # next week.
53: day += + 7 - (wday - next_wday)
54: if day > month_days(year, month)
55: day -= month_days(year, month)
56: month += 1
57: end
58: wday = next_wday
59: retry
60: end
61:
62: day += (next_wday - wday)
63: wday = next_wday
64: end
65: elsif !wday_restricted? and day_restricted?
66: # unrestricted wday, restricted day. go by day
67: month_days = (1 .. month_days(year, month))
68: days = @day.select do |d| month_days === d end
69: unless days.include?(day)
70: next_day = days.detect(lambda { days.min }) do |d| d > day end
71: hour, min, sec = @hour.min, @min.min, @sec.min
72: if next_day.nil? or next_day < day
73: day = next_day.nil? ? @day.min : next_day
74: month += 1
75: retry
76: end
77: day = next_day
78: end
79: else
80: # both @day and @wday are restricted, or unrestricted
81: month_days = (1 .. month_days(year, month))
82: days = @day.select do |d| month_days === d end
83: unless days.include?(day) || @wday.include?(wday)
84: next_day = days.detect(lambda { days.min }) do |d| d > day end
85: next_wday = @wday.detect(lambda { @wday.min }) do |w| w > wday end
86: hour, min, sec = @hour.min, @min.min, @sec.min
87:
88: # which is less? next_day or next_wday?
89: # just calculate how many days from 'day' they both are.
90:
91: if next_day.nil? or next_day < day
92: next_by_mday = month_days(year, month) - day + (next_day.nil? ? @day.min : next_day)
93: else
94: next_by_mday = next_day - day
95: end
96:
97: if next_wday.nil? or next_wday < wday
98: next_by_wday = 7 - wday + (next_wday.nil? ? @day.min : next_wday)
99: else
100: next_by_wday = next_wday - wday
101: end
102:
103: next_day = [next_by_wday, next_by_mday].min
104: if next_day + day > month_days(year, month)
105: # next fire lands on next month
106: day += next_day - month_days(year, month)
107: wday += next_day % 7
108: wday -= 7 if wday > 6
109: month += 1
110: if month > 12
111: year += 1
112: month = 1
113: end
114: retry
115: end
116: day += next_day
117: end
118: end
119:
120:
121:
122: # hour
123: unless @hour.include?(hour)
124: next_hour = @hour.detect(lambda { @hour.min }) do |h| h > hour end
125: min, sec = @min.min, @sec.min
126: if next_hour < hour
127: hour = next_hour
128: day += 1
129: retry
130: end
131: hour = next_hour
132: end
133:
134: # min
135: unless @min.include?(min)
136: next_min = @min.detect(lambda { @min.min }) do |m| m > min end
137: sec = @sec.min
138: if next_min < min
139: min = next_min
140: hour += 1
141: retry
142: end
143: min = next_min
144: end
145:
146: # sec
147: unless @sec.include?(sec)
148: next_sec = @sec.detect(lambda { @sec.min }) do |s| s > sec end
149: if next_sec < sec
150: sec = next_sec
151: min += 1
152: retry
153: end
154: sec = next_sec
155: end
156:
157: break
158: end
159:
160: Time.local sec, min, hour, day, month, year, wday, yday, isdst, zone
161: end
[ show source ]
# File server/cron_trigger.rb, line 180
180: def hour=(hour)
181: @hour = parse_part(hour, 0 .. 23)
182: end
[ show source ]
# File server/cron_trigger.rb, line 176
176: def min=(min)
177: @min = parse_part(min, 0 .. 59)
178: end
[ show source ]
# File server/cron_trigger.rb, line 188
188: def month=(month)
189: @month = parse_part(month, 1 .. 12)
190: end
TODO: mimic attr_reader to define all of these
[ show source ]
# File server/cron_trigger.rb, line 172
172: def sec=(sec)
173: @sec = parse_part(sec, 0 .. 59)
174: end
[ show source ]
# File server/cron_trigger.rb, line 196
196: def wday=(wday)
197: @wday = parse_part(wday, 0 .. 6)
198: end
[ show source ]
# File server/cron_trigger.rb, line 167
167: def wday_restricted?
168: return !@wday.eql?(0..6)
169: end
[ show source ]
# File server/cron_trigger.rb, line 192
192: def year=(year)
193: @year = parse_part(year)
194: end