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)
          zt.add((60 - nt.min) * 60 - nt.sec)
          next
        end
        unless sub_match?(nt, :min, @minutes)
          zt.add(60 - nt.sec)
          next
        end
        unless sub_match?(nt, :sec, @seconds)
          zt.add(next_second(nt))
          next
        end

        break
      end

      nt
    end
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)
          zt.add((60 - nt.min) * 60 - nt.sec)
          next
        end
        unless sub_match?(nt, :min, @minutes)
          zt.add(60 - nt.sec)
          next
        end
        unless sub_match?(nt, :sec, @seconds)
          zt.add(next_second(nt))
          next
        end

        break
      end

      nt
    end
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::Scheduler::CronLine.new('30 7 * * *').next_time(
     Time.mktime(2008, 10, 24, 7, 29))
   #=> Fri Oct 24 07:30:00 -0500 2008

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

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