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