Class: Timely::WeekDays

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

Constant Summary collapse

WEEKDAY_KEYS =
%i[sun mon tue wed thu fri sat]

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
53
# 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 Integer
    # 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 Integer, 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



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

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

#all_days?Boolean

Returns true if all days are selected

Returns:

  • (Boolean)


91
92
93
# File 'lib/timely/week_days.rb', line 91

def all_days?
  @weekdays.all? { |_day, day_selected| day_selected }
end

#applies_for_date?(date) ⇒ Boolean

Returns:

  • (Boolean)


72
73
74
# File 'lib/timely/week_days.rb', line 72

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)


79
80
81
82
# File 'lib/timely/week_days.rb', line 79

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

#number_of_occurances_in(range) ⇒ Object



84
85
86
87
88
# File 'lib/timely/week_days.rb', line 84

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



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

def set_day(day, set)
  key = day_to_index(day)
  unless WEEKDAY_KEYS.include?(key)
    raise ArgumentError, "Invalid week day index #{key}"
  end
  @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’



106
107
108
109
110
111
# File 'lib/timely/week_days.rb', line 106

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]



97
98
99
100
101
102
# File 'lib/timely/week_days.rb', line 97

def weekdays
  selected = @weekdays.select { |_day, day_selected| day_selected }
  # Ruby 1.8 returns an array for Hash#select and loses order
  return selected.keys if selected.is_a?(Hash)
  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



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

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