Sha256: 85074675267af71e502fcf15b3161c22958c33816b76cb0e2e7742921a670b1f

Contents?: true

Size: 1.8 KB

Versions: 1

Compression:

Stored size: 1.8 KB

Contents

module Crono
  # Period describe frequency of jobs
  class Period
    DAYS = [:monday, :tuesday, :wednesday, :thursday, :friday, :saturday,
            :sunday]

    def initialize(period, at: nil, on: nil)
      @period = period
      @at_hour, @at_min = parse_at(at) if at
      @on = parse_on(on) if on
    end

    def next(since: nil)
      return initial_next unless since
      @next = @period.since(since)
      @next = @next.beginning_of_week.advance(days: @on) if @on
      @next = @next.change(time_atts)
      return @next if @next.future?
      Time.now
    end

    def description
      desc = "every #{@period.inspect}"
      desc += format(' at %.2i:%.2i', @at_hour, @at_min) if @at_hour && @at_min
      desc += " on #{DAYS[@on].capitalize}" if @on
      desc
    end

    private

    def initial_next
      next_time = initial_day.change(time_atts)
      return next_time if next_time.future?
      @period.from_now.change(time_atts)
    end

    def initial_day
      return Time.now unless @on
      day = Time.now.beginning_of_week.advance(days: @on)
      return day if day.future?
      @period.from_now.beginning_of_week.advance(days: @on)
    end

    def parse_on(on)
      day_number = DAYS.index(on)
      fail "Wrong 'on' day" unless day_number
      fail "period should be at least 1 week to use 'on'" if @period < 1.week
      day_number
    end

    def parse_at(at)
      if @period < 1.day && (at.is_a? String || at[:hour])
        fail "period should be at least 1 day to use 'at' with specified hour"
      end

      case at
      when String
        time = Time.parse(at)
        return time.hour, time.min
      when Hash
        return at[:hour], at[:min]
      else
        fail "Unknown 'at' format"
      end
    end

    def time_atts
      { hour: @at_hour, min: @at_min }.compact
    end
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
crono-0.9.0 lib/crono/period.rb