lib/rufus/scheduler/cronline.rb in rufus-scheduler-3.3.1 vs lib/rufus/scheduler/cronline.rb in rufus-scheduler-3.3.2
- old
+ new
@@ -1,7 +1,7 @@
#--
-# Copyright (c) 2006-2016, John Mettraux, jmettraux@gmail.com
+# Copyright (c) 2006-2017, John Mettraux, jmettraux@gmail.com
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
@@ -31,10 +31,15 @@
# A 'cron line' is a line in the sense of a crontab
# (man 5 crontab) file line.
#
class CronLine
+ # The max number of years in the future or the past before giving up
+ # searching for #next_time or #previous_time respectively
+ #
+ NEXT_TIME_MAX_YEARS = 14
+
# The string used for creating this cronline instance.
#
attr_reader :original
attr_reader :original_timezone
@@ -135,15 +140,21 @@
#
def next_time(from=ZoTime.now)
nt = nil
zt = ZoTime.new(from.to_i + 1, @timezone)
+ maxy = from.year + NEXT_TIME_MAX_YEARS
loop do
nt = zt.dup
+ fail RangeError.new(
+ "failed to reach occurrence within " +
+ "#{NEXT_TIME_MAX_YEARS} years for '#{original}'"
+ ) if nt.year > maxy
+
unless date_match?(nt)
zt.add((24 - nt.hour) * 3600 - nt.min * 60 - nt.sec)
next
end
unless sub_match?(nt, :hour, @hours)
@@ -166,19 +177,25 @@
end
# Returns the previous time the cronline matched. It's like next_time, but
# for the past.
#
- def previous_time(from=Time.now)
+ def previous_time(from=ZoTime.now)
pt = nil
zt = ZoTime.new(from.to_i - 1, @timezone)
+ miny = from.year - NEXT_TIME_MAX_YEARS
loop do
pt = zt.dup
+ fail RangeError.new(
+ "failed to reach occurrence within " +
+ "#{NEXT_TIME_MAX_YEARS} years for '#{original}'"
+ ) if pt.year < miny
+
unless date_match?(pt)
zt.substract(pt.hour * 3600 + pt.min * 60 + pt.sec + 1)
next
end
unless sub_match?(pt, :hour, @hours)
@@ -277,12 +294,14 @@
#st = Time.now
t1 = next_time(t0)
#p Time.now - st
d = t1 - t0
delta = d if d < delta
-
- break if @months == nil && t1.month == 2
+ break if @months.nil? && t1.month == 2
+ break if @months.nil? && @days.nil? && t1.day == 2
+ break if @months.nil? && @days.nil? && @hours.nil? && t1.hour == 1
+ break if @months.nil? && @days.nil? && @hours.nil? && @minutes.nil? && t1.min == 1
break if t1.year >= 2001
t0 = t1
end
@@ -486,12 +505,18 @@
def date_match?(zt)
return false unless sub_match?(zt, :day, @days)
return false unless sub_match?(zt, :month, @months)
+
+ return true if (
+ (@weekdays && @monthdays) &&
+ (sub_match?(zt, :wday, @weekdays) ||
+ sub_match?(zt, :monthdays, @monthdays)))
+
return false unless sub_match?(zt, :wday, @weekdays)
- #return false unless monthday_match?(zt, @monthdays)
return false unless sub_match?(zt, :monthdays, @monthdays)
+
true
end
end
end