Class: Timely::WeekDays

Inherits:
Object
  • Object
show all
Defined in:
lib/timely/week_days.rb

Constant Summary collapse

WEEKDAY_KEYS =
[:sun, :mon, :tue, :wed, :thu, :fri, :sat]
ALL_WEEKDAYS =
WeekDays.new(%w(1 1 1 1 1 1 1))

Instance Method Summary collapse

Constructor Details

#initialize(weekdays) ⇒ WeekDays

Create a new Weekdays object weekdays can be in three formats integer representing binary string

e.g. 1 = Sun, 2 = Mon, 3 = Sun + Mon, etc.

hash with symbol keys for :sun, :mon, … with true/false values

e.g. {:sun => true, :tue => true} is Sunday and Tuesday
Not passing in values is the same as setting them explicitly to true

array with true/false values from sun to sat

e.g. [1, 0, 1, 0, 0, 0, 0] is Sunday and Tuesday


14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
# File 'lib/timely/week_days.rb', line 14

def initialize(weekdays)
  @weekdays = {
    :sun => false,
    :mon => false,
    :tue => false,
    :wed => false,
    :thu => false,
    :fri => false,
    :sat => false
  }

  case weekdays
  when Fixnum
    # 4 -> 0000100 (binary) -> "0010000" (reversed string) -> {:tue => true}
    weekdays.to_s(2).reverse.each_char.with_index do |char, index|
      set_day(index, char == '1')
    end
  when Hash
    weekdays.each_pair do |day, value|
      set_day(day, value)
    end
  when Array
    weekdays.each.with_index do |value, index|
      set_day(index, value)
    end
  when NilClass
    @weekdays = {
      :sun => true,
      :mon => true,
      :tue => true,
      :wed => true,
      :thu => true,
      :fri => true,
      :sat => true
    }
  else
    raise ArgumentError, "You must initialize with an Fixnum, Hash or Array"
  end
end

Instance Method Details

#[]=(day, set) ⇒ Object

Set the weekday on or off weekdays = true weekdays = false set ideally will be true, but ‘true’, 1 and ‘1’ are accepted All other values will be treated as false



59
60
61
# File 'lib/timely/week_days.rb', line 59

def []=(day, set)
  set_day(day, set)
end

#all_days?Boolean

Returns true if all days are selected

Returns:

  • (Boolean)


94
95
96
# File 'lib/timely/week_days.rb', line 94

def all_days?
  @weekdays.all?{|day, selected| selected}
end

#applies_for_date?(date) ⇒ Boolean

Returns:

  • (Boolean)


75
76
77
# File 'lib/timely/week_days.rb', line 75

def applies_for_date?(date)
  has_day?(date.wday)
end

#has_day?(weekday) ⇒ Boolean

Determine if weekdays has day selected Accepts either symbol or integer e.g. :sun or 0 = Sunday, :sat or 6 = Saturday

Returns:

  • (Boolean)


82
83
84
85
# File 'lib/timely/week_days.rb', line 82

def has_day?(weekday)
  weekday = WEEKDAY_KEYS[weekday] if weekday.is_a?(Fixnum)
  @weekdays[weekday]
end

#number_of_occurances_in(range) ⇒ Object



87
88
89
90
91
# File 'lib/timely/week_days.rb', line 87

def number_of_occurances_in(range)
  range.inject(0) do |count, date|
    applies_for_date?(date) ? count+1 : count
  end
end

#set_day(day, set) ⇒ Object

Raises:

  • (ArgumentError)


63
64
65
66
67
68
69
70
71
72
73
# File 'lib/timely/week_days.rb', line 63

def set_day(day, set)
  key = if day.is_a?(Fixnum)
    WEEKDAY_KEYS[day]
  elsif day.is_a?(String)
    day.to_sym
  else
    day
  end
  raise ArgumentError, "Invalid week day index #{key}" unless WEEKDAY_KEYS.include?(key)
  @weekdays[key] = [true, 'true', 1, '1'].include?(set)
end

#to_sObject

Returns comma separated and capitalized in Sun-Sat order e.g. ‘Mon, Tue, Wed’ or ‘Sat’ or ‘Sun, Sat’



108
109
110
111
112
113
# File 'lib/timely/week_days.rb', line 108

def to_s
  days = weekdays.map{|day| day.to_s.capitalize}
  last_day = days.pop

  days.empty? ? last_day : days.join(", ") + ", and " + last_day
end

#weekdaysObject

Returns array of weekday selected e.g. [:sun, :sat]



100
101
102
103
104
# File 'lib/timely/week_days.rb', line 100

def weekdays
  selected = @weekdays.select{|day, selected| selected}
  # Ruby 1.8 returns an array for Hash#select and loses order
  selected.is_a?(Hash) ? selected.keys : selected.map(&:first).sort_by{|v| WEEKDAY_KEYS.index(v)}
end

#weekdays_intObject

7 bits encoded in decimal number 0th bit = Sunday, 6th bit = Saturday Value of 127 => all days are on



118
119
120
121
122
123
124
# File 'lib/timely/week_days.rb', line 118

def weekdays_int
  int = 0
  WEEKDAY_KEYS.each.with_index do |day, index|
    int += 2 ** index if @weekdays[day]
  end
  int
end