class Runt::WeekInterval

This class creates an expression which matches dates occuring during the weeks alternating at the given interval begining on the week containing the date used to create the instance.

WeekInterval.new(starting_date, interval)

Weeks are defined as Sunday to Saturday, as opposed to the commercial week which starts on a Monday. For example,

every_other_week = WeekInterval.new(Date.new(2013,04,24), 2)

will match any date that occurs during every other week begining with the week of 2013-04-21 (2013-04-24 is a Wednesday and 2013-04-21 is the Sunday that begins the containing week).

# Sunday of starting week
every_other_week.include?(Date.new(2013,04,21)) #==> true
# Saturday of starting week
every_other_week.include?(Date.new(2013,04,27)) #==> true
# First week _after_ start week
every_other_week.include?(Date.new(2013,05,01)) #==> false
# Second week _after_ start week
every_other_week.include?(Date.new(2013,05,06)) #==> true

NOTE: The idea and tests for this class were originally contributed as the REWeekWithIntervalTE class by Jeff Whitmire. The behavior of the original class provided both the matching of every n weeks and the specification of specific days of that week in a single class. This class only provides the matching of every n weeks. The exact functionality of the original class is easy to create using the Runt set operators and the DIWeek class:

# Old way
tu_thurs_every_third_week = REWeekWithIntervalTE.new(Date.new(2013,04,24),2,[2,4])

# New way
tu_thurs_every_third_week = 
    WeekInterval.new(Date.new(2013,04,24),2) & (DIWeek.new(Tuesday) | DIWeek.new(Thursday))

Notice that the compound expression (in parens after the “&”) can be replaced or combined with any other appropriate temporal expression to provide different functionality (REWeek to provide a range of days, REDay to provide certain times, etc…).

Contributed by Jeff Whitmire

Public Class Methods

new(start_date,interval=2) click to toggle source
# File lib/runt/temporalexpression.rb, line 869
def initialize(start_date,interval=2)
  @start_date = DPrecision.to_p(start_date,DPrecision::DAY)
  # convert base_date to the start of the week
  @base_date = @start_date - @start_date.wday
  @interval = interval
end

Public Instance Methods

include?(date) click to toggle source
# File lib/runt/temporalexpression.rb, line 876
def include?(date)
      return false if @base_date > date
      ((adjust_for_year(date) - week_num(@base_date)) % @interval) == 0 
end
to_s() click to toggle source
# File lib/runt/temporalexpression.rb, line 881
def to_s
  "every #{Runt.ordinalize(@interval)} week starting with the week containing #{Runt.format_date(@start_date)}"
end

Private Instance Methods

adjust_for_year(date) click to toggle source
# File lib/runt/temporalexpression.rb, line 899
def adjust_for_year(date)
      # Exclusive range: if date.year == @base_date.year, this will be empty
      range_of_years = @base_date.year...date.year
      in_same_year = range_of_years.to_a.empty?
      # Week number of the given date argument
      week_number = week_num(date)
      # Default (most common case) date argument is in same year as @base_date
  # and the week number is also part of the same year. This starting value
      # is also necessary for the case where they're not in the same year.
      adjustment = week_number
      if in_same_year && (week_number < week_num(@base_date)) then
        # The given date occurs within the same year
        # but is actually week number 1 of the next year
        adjustment = adjustment + max_week_num(date.year)
      elsif !in_same_year then
        # Date occurs in different year
        range_of_years.each do |year|
          # Max week number taking into account we are not using commercial week
          adjustment = adjustment + max_week_num(year)
        end
      end
      adjustment
end
max_week_num(year) click to toggle source
# File lib/runt/temporalexpression.rb, line 890
def max_week_num(year)        
      d = Date.new(year,12,31)
      max = week_num(d)
      while max < 52
        d = d - 1
        max = week_num(d)
      end
      max
end
week_num(date) click to toggle source
# File lib/runt/temporalexpression.rb, line 886
def week_num(date)
      # %U - Week number of the year. The week starts with Sunday.  (00..53)
      date.strftime("%U").to_i    
end