Sha256: f86296e412158f39e06ac014988775cbd0fea1381f600b2135da975f17bd2df4

Contents?: true

Size: 1.61 KB

Versions: 1

Compression:

Stored size: 1.61 KB

Contents

# frozen_string_literal: true

require_relative "day_range/version"

# A Range-like object that represents a range of days.
class DayRange < Range
  class Error < StandardError; end

  # Returns the number of days in the timeframe.
  def days
    last - first + 1
  end

  # Returns an enumerator that steps over the days in the range with specific
  # intervals.
  #
  # step can be specified similarily to DateTime#advance argument
  #
  # Usage examples
  #
  #     day_range.every(days: 42)
  #     day_range.every(weeks: 1)
  #     day_range.every(months: 1)
  #     day_range.every(days: 1, months: 2, years: 3)
  #
  def every(step)
    c_date = first
    finish_date = last
    comparison_operator = exclude_end? ? :< : :<=

    result = []
    while c_date.send(comparison_operator, finish_date)
      result << c_date
      yield c_date if block_given?
      c_date = advance(c_date, step)
    end
    result
  end

  # Returns a DayRange with the same length as this one, starting on the day
  # after this one ends.
  def next
    self.class.new(
      last.next_day,
      last + days
    )
  end

  # Returns a DayRange with the same length as this one, ending on the day
  # before this one starts.
  def previous
    self.class.new(
      first - days,
      first.prev_day
    )
  end

  private

  # File activesupport/lib/active_support/core_ext/date/calculations.rb, line 112
  def advance(date, options)
    d = date

    d = d >> options[:years] * 12 if options[:years]
    d = d >> options[:months] if options[:months]
    d += options[:weeks] * 7 if options[:weeks]
    d += options[:days] if options[:days]

    d
  end
end

Version data entries

1 entries across 1 versions & 1 rubygems

Version Path
dayrange-1.0.0 lib/day_range.rb