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].freeze

Class Method Summary collapse

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


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
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/timely/week_days.rb', line 26

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

Class Method Details

.from_range(date_range) ⇒ Object



7
8
9
10
11
12
13
14
15
# File 'lib/timely/week_days.rb', line 7

def self.from_range(date_range)
  dates = Array(date_range)
  return ALL_WEEKDAYS if dates.count >= WEEKDAY_KEYS.count

  new(dates.each_with_object({}) do |date, result|
    # e.g. {3: true, 5: true}
    result[date.to_date.wday] = true
  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



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

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

#all_days?Boolean

Returns true if all days are selected

Returns:

  • (Boolean)


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

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

#applies_for_date?(date) ⇒ Boolean

Returns:

  • (Boolean)


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

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)


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

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

#number_of_occurances_in(range) ⇒ Object



95
96
97
98
99
# File 'lib/timely/week_days.rb', line 95

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)


76
77
78
79
80
81
# File 'lib/timely/week_days.rb', line 76

def set_day(day, set)
  key = day_to_index(day)
  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’



114
115
116
117
118
119
# File 'lib/timely/week_days.rb', line 114

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]



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

def weekdays
  @weekdays.select { |_day, day_selected| day_selected }.keys
end

#weekdays_intObject

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



124
125
126
127
128
129
130
# File 'lib/timely/week_days.rb', line 124

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