Class: Aef::Weekling::WeekDay

Inherits:
Object
  • Object
show all
Includes:
Comparable
Defined in:
lib/aef/weekling/week_day.rb

Overview

Immutable object representing a calendar week day (according to ISO 8601).

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(week_day) ⇒ WeekDay #initialize(date) ⇒ WeekDay #initialize(week, day) ⇒ WeekDay #initialize(year, week_index, day) ⇒ WeekDay

Returns a new instance of WeekDay.

Overloads:

  • #initialize(week_day) ⇒ WeekDay

    Initialize by a week-day-like object.

    Parameters:

  • #initialize(date) ⇒ WeekDay

    Initialize by a date-like object.

    Parameters:

    • date (Date, DateTime, Time)

      a date-like object

  • #initialize(week, day) ⇒ WeekDay

    Initialize by week-like-object and a day.

    Parameters:

    • week (Aef::Weekling::Week)

      a week-like object

    • day (Integer, Symbol)

      either a day number or a lowercase english day name

  • #initialize(year, week_index, day) ⇒ WeekDay

    Initialize by year, week number and day.

    Parameters:

    • year (Integer, Aef::Weekling::Year)

      a year

    • week_number (Integer)

      a weeks index

    • day (Integer, Symbol)

      either a day number or a lowercase english day name

Raises:

  • (ArgumentError)


99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/aef/weekling/week_day.rb', line 99

def initialize(*arguments)
  case arguments.count
  when 1
    object = arguments.first
    if [:week, :index].all?{|method_name| object.respond_to?(method_name) }
      @week  = object.week.to_week
      @index = object.index.to_i
    elsif object.respond_to?(:to_date)
      date = object.to_date
      @week  = Week.new(date)
      @index = ((date.wday - 1) % 7) + 1
    else
      raise ArgumentError, 'A single argument must either respond to #week and #index or to #to_date'
    end
  when 2
    week, day = *arguments
    @week = week.to_week
    if day.respond_to?(:to_i)
      @index = day.to_i
    else
      raise ArgumentError, 'Invalid day symbol' unless @index = SYMBOL_TO_INDEX_TABLE[day.to_sym]
    end
  when 3
    year, week_index, day = *arguments
    @week = Week.new(year, week_index)
    if day.respond_to?(:to_i)
      @index = day.to_i
    else
      raise ArgumentError, 'Invalid day symbol' unless @index = SYMBOL_TO_INDEX_TABLE[day.to_sym]
    end
  else
    raise ArgumentError, "wrong number of arguments (#{arguments.count} for 1..3)"
  end
    
  raise ArgumentError, 'Index must be in 1..7' unless (1..7).include?(index)
end

Instance Attribute Details

#indexInteger (readonly)

Returns the number of the day in its week.

Returns:

  • (Integer)

    the number of the day in its week



78
79
80
# File 'lib/aef/weekling/week_day.rb', line 78

def index
  @index
end

#weekAef::Weekling::Week (readonly)

Returns the week the day is part of.

Returns:



75
76
77
# File 'lib/aef/weekling/week_day.rb', line 75

def week
  @week
end

Class Method Details

.parse(string) ⇒ Aef::Weekling::WeekDay

Note:

Looks for patterns like this: 2011-W03-5

Parses the first week day out of a string.

Parameters:

  • string (String)

    a string containing a week-day representation

Returns:

Raises:

  • (ArgumentError)

    if pattern cannot be found



64
65
66
67
68
69
70
71
# File 'lib/aef/weekling/week_day.rb', line 64

def parse(string)
  if sub_matches = PARSE_PATTERN.match(string.to_s)
    original, year, week_index, day_index = *sub_matches
    new(year.to_i, week_index.to_i, day_index.to_i)
  else
    raise ArgumentError, 'No week day found for parsing'
  end
end

.todayAef::Weekling::WeekDay Also known as: now

Initializes the current week day.

Returns:



49
50
51
52
53
# File 'lib/aef/weekling/week_day.rb', line 49

def today
  today = Date.today

  new(today, ((today.wday - 1) % 7) + 1)
end

Instance Method Details

#+(other) ⇒ Aef::Weekling::WeekDay

Adds days to the week-day.

Examples:

28 days after 2007-W01-1

Aef::Weekling::WeekDay.new(2007, 1, 1) + 28
# => #<Aef::Weekling::WeekDay: 2007-W05-1>

Parameters:

  • other (Integer)

    number of days to add

Returns:



270
271
272
273
274
275
276
277
278
279
280
281
282
283
# File 'lib/aef/weekling/week_day.rb', line 270

def +(other)
  result = self
  number = other.to_i

  number.abs.times do
    if number < 0
      result = result.previous
    else
      result = result.next
    end
  end

  result
end

#-(other) ⇒ Aef::Weekling::WeekDay

Subtracts days from the week-day.

Examples:

5 days before 2012-W45-3

Aef::Weekling::WeekDay.new(2012, 45, 3) - 5
# => #<Aef::Weekling::WeekDay: 2012-W44-5>

Parameters:

  • other (Integer)

    number of days to subtract

Returns:



293
294
295
# File 'lib/aef/weekling/week_day.rb', line 293

def -(other)
  self + -other.to_i
end

#<=>(other) ⇒ -1, ...

Compares the week-day with another to determine its relative position.

Parameters:

Returns:

  • (-1, 0, 1)

    -1 if other is greater, 0 if other is equal and 1 if other is lesser than self



208
209
210
211
212
213
214
215
# File 'lib/aef/weekling/week_day.rb', line 208

def <=>(other)
  other_week_day = self.class.new(other)

  week_comparison = week <=> other_week_day.week
    
  return index <=> other_week_day.index if week_comparison == 0
  return week_comparison
end

#==(other) ⇒ true, false

Returns true if other lies in the same week and has the same index.

Parameters:

Returns:

  • (true, false)

    true if other lies in the same week and has the same index



185
186
187
188
189
# File 'lib/aef/weekling/week_day.rb', line 185

def ==(other)
  other_week_day = self.class.new(other)

  week == other_week_day.week and index == other_week_day.index
end

#eql?(other) ⇒ true, false

Returns true if other lies in the same year, has the same index and is of the same or a descending class.

Parameters:

Returns:

  • (true, false)

    true if other lies in the same year, has the same index and is of the same or a descending class



194
195
196
# File 'lib/aef/weekling/week_day.rb', line 194

def eql?(other)
  other.is_a?(self.class) and self == other
end

#friday?true, false

Returns true if week day is friday.

Returns:

  • (true, false)

    true if week day is friday



318
319
320
# File 'lib/aef/weekling/week_day.rb', line 318

def friday?
  to_sym == :friday
end

#hashsee Array#hash

Returns identity hash for hash table usage.

Returns:

  • (see Array#hash)

    identity hash for hash table usage



199
200
201
# File 'lib/aef/weekling/week_day.rb', line 199

def hash
  [week, index].hash
end

#inspectString

Represents a week-day as String for debugging.

Examples:

Output of friday in 42nd week of 2525

Aef::Weekling::WeekDay.new(2525, 42, 5)
# => "#<Aef::Weekling::WeekDay: 2525-W42-5>"

Returns:

  • (String)

    a character representation for debugging



154
155
156
# File 'lib/aef/weekling/week_day.rb', line 154

def inspect
  "#<#{self.class.name}: #{to_s}>"
end

#monday?true, false

Returns true if week day is monday.

Returns:

  • (true, false)

    true if week day is monday



298
299
300
# File 'lib/aef/weekling/week_day.rb', line 298

def monday?
  to_sym == :monday
end

#nextAef::Weekling::WeekDay Also known as: succ

Finds the following week-day.

Examples:

The thursday after some wednesday

some_day = Aef::Weekling::WeekDay.new(2013, 33, 3)
some_day.next
# => #<Aef::Weekling::WeekDay: 2013-W33-4>

The week-day after a year’s last week-day

last_week_day_in_year = Aef::Weekling::WeekDay.new(1998, 53, 7)
last_week_day_in_year.next
# => #<Aef::Weekling::WeekDay: 1999-W01-1>

Returns:



230
231
232
233
234
235
236
# File 'lib/aef/weekling/week_day.rb', line 230

def next
  if index == 7
    self.class.new(week.next, 1)
  else
    self.class.new(week, index + 1)
  end
end

#previousAef::Weekling::WeekDay Also known as: pred

Find the previous week-day

Examples:

The sunday before some monday

some_week = Aef::Weekling::WeekDay.new(1783, 16, 1)
some_week.previous
# => #<Aef::Weekling::WeekDay: 1783-W15-7>

The week-day before first week-day of a year

first_week_in_year = Aef::Weekling::WeekDay.new(2014, 1, 1)
first_week_in_year.previous
# => #<Aef::Weekling::WeekDay: 2013-W52-7>

Returns:



252
253
254
255
256
257
258
# File 'lib/aef/weekling/week_day.rb', line 252

def previous
  if index == 1
    self.class.new(week.previous, 7)
  else
    self.class.new(week, index - 1)
  end
end

#saturday?true, false

Returns true if week day is saturday.

Returns:

  • (true, false)

    true if week day is saturday



323
324
325
# File 'lib/aef/weekling/week_day.rb', line 323

def saturday?
  to_sym == :saturday
end

#sunday?true, false

Returns true if week day is sunday.

Returns:

  • (true, false)

    true if week day is sunday



328
329
330
# File 'lib/aef/weekling/week_day.rb', line 328

def sunday?
  to_sym == :sunday
end

#thursday?true, false

Returns true if week day is thursday.

Returns:

  • (true, false)

    true if week day is thursday



313
314
315
# File 'lib/aef/weekling/week_day.rb', line 313

def thursday?
  to_sym == :thursday
end

#to_dateDate

Returns the date of the week-day.

Returns:

  • (Date)

    the date of the week-day



166
167
168
169
170
171
172
173
174
175
# File 'lib/aef/weekling/week_day.rb', line 166

def to_date
  date = Date.new(week.year.to_i, 1, 1)
    
  days_to_add = 7 * week.index
  days_to_add -= 7 if date.cweek == 1
  days_to_add -= ((date.wday - 1) % 7) + 1
  days_to_add += index
    
  date + days_to_add
end

#to_sString

Represents a week-day as String in ISO 8601 format.

Examples:

Output of friday in 42nd week of 2525

Aef::Weekling::WeekDay.new(2525, 42, 5).to_s
# => "2525-W42-5"

Returns:

  • (String)

    a character representation of the week day



143
144
145
# File 'lib/aef/weekling/week_day.rb', line 143

def to_s
  "#{week}-#{index}"
end

#to_symSymbol

Returns a symbolic representation of the week day.

Returns:

  • (Symbol)

    a symbolic representation of the week day



159
160
161
# File 'lib/aef/weekling/week_day.rb', line 159

def to_sym
  SYMBOL_TO_INDEX_TABLE.invert[index]
end

#to_week_dayAef::Weekling::WeekDay

Returns self reference.

Returns:



178
179
180
# File 'lib/aef/weekling/week_day.rb', line 178

def to_week_day
  self
end

#tuesday?true, false

Returns true if week day is tuesday.

Returns:

  • (true, false)

    true if week day is tuesday



303
304
305
# File 'lib/aef/weekling/week_day.rb', line 303

def tuesday?
  to_sym == :tuesday
end

#wednesday?true, false

Returns true if week day is wednesday.

Returns:

  • (true, false)

    true if week day is wednesday



308
309
310
# File 'lib/aef/weekling/week_day.rb', line 308

def wednesday?
  to_sym == :wednesday
end

#weekend?true, false

Returns true if week day is saturday or sunday.

Returns:

  • (true, false)

    true if week day is saturday or sunday



333
334
335
# File 'lib/aef/weekling/week_day.rb', line 333

def weekend?
  saturday? or sunday?
end