Class: Aef::Weekling::Week

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

Overview

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

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(week) ⇒ Week #initialize(date) ⇒ Week #initialize(year, index) ⇒ Week

Returns a new instance of Week.

Overloads:

  • #initialize(week) ⇒ Week

    Initialize by a week-like object.

    Parameters:

  • #initialize(date) ⇒ Week

    Initialize by a date-like object.

    Parameters:

    • date (Date, DateTime, Time)

      a date-like object

  • #initialize(year, index) ⇒ Week

    Initialize by year and week number.

    Parameters:



80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/aef/weekling/week.rb', line 80

def initialize(*arguments)
  case arguments.count
  when 1
    object = arguments.first
    if [:year, :index].all?{|method_name| object.respond_to?(method_name) }
      @year  = object.year.to_year
      @index = object.index.to_i
    elsif object.respond_to?(:to_date)
      date = object.to_date
      @year  = Year.new(date.cwyear)
      @index = date.cweek
    else
      raise ArgumentError, 'A single argument must either respond to #year and #index or to #to_date'
    end
  when 2
    year, index = *arguments
    @year  = Year.new(year)
    @index = index.to_i
  else
    raise ArgumentError, "wrong number of arguments (#{arguments.count} for 1..2)"
  end
    
  if not (1..52).include?(@index)
    if @index == 53
      if @year.week_count == 52
        raise ArgumentError, "Index #{@index} is invalid. Year #{@year} has only 52 weeks"
      end
    else
      raise ArgumentError, "Index #{@index} is invalid. Index can never be lower than 1 or higher than 53"
    end
  end
    
end

Instance Attribute Details

#indexInteger (readonly)

Returns the number of the week in its year.

Returns:

  • (Integer)

    the number of the week in its year



66
67
68
# File 'lib/aef/weekling/week.rb', line 66

def index
  @index
end

#yearAef::Weekling::Year (readonly)

Returns the year the week is part of.

Returns:



63
64
65
# File 'lib/aef/weekling/week.rb', line 63

def year
  @year
end

Class Method Details

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

Note:

Looks for patterns like this: 2011-W03

Parses the first week out of a string.

Parameters:

  • string (String)

    a string containing a week representation

Returns:

Raises:

  • (ArgumentError)

    if pattern cannot be found



52
53
54
55
56
57
58
59
# File 'lib/aef/weekling/week.rb', line 52

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

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

Initializes the current week.

Returns:



37
38
39
40
41
# File 'lib/aef/weekling/week.rb', line 37

def today
  today = Date.today

  new(today.year, today.cweek)
end

Instance Method Details

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

Adds weeks to the week.

Examples:

28 weeks after 2007-W01

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

Parameters:

  • other (Integer)

    number of weeks to add

Returns:



234
235
236
237
238
239
240
241
242
243
244
245
246
247
# File 'lib/aef/weekling/week.rb', line 234

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::Week

Subtracts weeks from the week.

Examples:

3 weeks before 2000-W03

Aef::Weekling::Week.new(2000, 3) - 3
# => #<Aef::Weekling::Week: 1999-W52>

Parameters:

  • other (Integer)

    number of weeks to subtract

Returns:



257
258
259
# File 'lib/aef/weekling/week.rb', line 257

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

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

Compares the week 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



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

def <=>(other)
  other_week = self.class.new(other)
  
  year_comparison = year <=> other_week.year
    
  return index <=> other_week.index if year_comparison == 0
  return year_comparison
end

#==(other) ⇒ true, false

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

Parameters:

Returns:

  • (true, false)

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



144
145
146
147
148
# File 'lib/aef/weekling/week.rb', line 144

def ==(other)
  other_week = self.class.new(other)
  
  year == other_week.year and index == other_week.index
end

#day(index) ⇒ Aef::Weekling::WeekDay #day(symbol) ⇒ Aef::Weekling::WeekDay

Returns the specified day of the week.

Overloads:

  • #day(index) ⇒ Aef::Weekling::WeekDay

    Returns a week-day by given index.

    Parameters:

    • the (Integer)

      index between 1 for monday and 7 for sunday

  • #day(symbol) ⇒ Aef::Weekling::WeekDay

    Returns a week-day by given symbol.

    Parameters:

    • the (Symbol)

      English name of the day in lowercase

Returns:



304
305
306
# File 'lib/aef/weekling/week.rb', line 304

def day(index_or_symbol)
  WeekDay.new(self, index_or_symbol)
end

#daysRange<Aef::Weekling::WeekDay>

Returns a range from monday to sunday.

Returns:



367
368
369
# File 'lib/aef/weekling/week.rb', line 367

def days
  monday..sunday
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



153
154
155
# File 'lib/aef/weekling/week.rb', line 153

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

#even?true, false

States if the week’s index is even.

Returns:

  • (true, false)

    true if the week is even



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

def even?
  @index.even?
end

#fridayAef::Weekling::WeekDay

Returns the week’s friday.

Returns:



339
340
341
# File 'lib/aef/weekling/week.rb', line 339

def friday
  day(:friday)
end

#hashsee Array#hash

Returns identity hash for hash table usage.

Returns:

  • (see Array#hash)

    identity hash for hash table usage



158
159
160
# File 'lib/aef/weekling/week.rb', line 158

def hash
  [year, index].hash
end

#inspectString

Represents a week as String for debugging.

Examples:

Output of the 13th week in 2012

Aef::Weekling::Week.new(2012, 13).inspect
# => "#<Aef::Weekling::Week: 2012-W13>"

Returns:

  • (String)

    a character representation for debugging



132
133
134
# File 'lib/aef/weekling/week.rb', line 132

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

#mondayAef::Weekling::WeekDay

Returns the week’s monday.

Returns:



311
312
313
# File 'lib/aef/weekling/week.rb', line 311

def monday
  day(:monday)
end

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

Finds the following week.

Examples:

The week after some other week

some_week = Aef::Weekling::Week.new(2012, 5)
some_week.next
# => #<Aef::Weekling::Week: 2012-W06>

The week after the last week of a year

last_week_in_year = Aef::Weekling::Week.new(2012, 52)
last_week_in_year.next
# => #<Aef::Weekling::Week: 2013-W01>

Returns:



189
190
191
192
193
194
195
196
197
# File 'lib/aef/weekling/week.rb', line 189

def next
  if index < 52
    self.class.new(year, index + 1)
  elsif year.week_count == 53 and index == 52
    self.class.new(year, index + 1)
  else
    self.class.new(year.next, 1)
  end
end

#odd?true, false

States if the week’s index is odd.

Returns:

  • (true, false)

    true if the week is odd



286
287
288
# File 'lib/aef/weekling/week.rb', line 286

def odd?
  @index.odd?
end

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

Find the previous week.

Examples:

The week before some other week

some_week = Aef::Weekling::Week.new(2012, 5)
some_week.previous
# => #<Aef::Weekling::Week: 2012-W04>

The week before the first week of a year

first_week_in_year = Aef::Weekling::Week.new(2016, 1)
first_week_in_year.previous
# => #<Aef::Weekling::Week: 2015-W53>

Returns:



214
215
216
217
218
219
220
221
222
# File 'lib/aef/weekling/week.rb', line 214

def previous
  if index > 1
    self.class.new(year, index - 1)
  elsif year.previous.week_count == 53
    self.class.new(year.previous, 53)
  else
    self.class.new(year.previous, 52)
  end
end

#saturdayAef::Weekling::WeekDay

Returns the week’s saturday.

Returns:



346
347
348
# File 'lib/aef/weekling/week.rb', line 346

def saturday
  day(:saturday)
end

#sundayAef::Weekling::WeekDay

Returns the week’s sunday.

Returns:



353
354
355
# File 'lib/aef/weekling/week.rb', line 353

def sunday
  day(:sunday)
end

#thursdayAef::Weekling::WeekDay

Returns the week’s thursday.

Returns:



332
333
334
# File 'lib/aef/weekling/week.rb', line 332

def thursday
  day(:thursday)
end

#to_sString

Represents a week as String in ISO 8601 format.

Examples:

Output of the 13th week in 2012

Aef::Weekling::Week.new(2012, 13).to_s
# => "2012-W13"

Returns:

  • (String)

    a character representation of the week



121
122
123
# File 'lib/aef/weekling/week.rb', line 121

def to_s
  "#{'%04i' % year}-W#{'%02i' % index}"
end

#to_weekAef::Weekling::Week

Returns self reference.

Returns:



137
138
139
# File 'lib/aef/weekling/week.rb', line 137

def to_week
  self
end

#tuesdayAef::Weekling::WeekDay

Returns the week’s tuesday.

Returns:



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

def tuesday
  day(:tuesday)
end

#until_index(end_index) ⇒ Range<Aef::Weekling::Week>

Returns a range of weeks beginning with self and ending with the first following week with the given index.

Examples:

End index higher than start index

Aef::Weekling::Week.new(2012, 35).until_index(50)
# => #<Aef::Weekling::Week: 2012-W35>..#<Aef::Weekling::Week: 2012-W50>

End index lower or equal than start index

Aef::Weekling::Week.new(2012, 35).until_index(11)
# => #<Aef::Weekling::Week: 2012-W35>..#<Aef::Weekling::Week:2013-W11>

Parameters:

  • end_index (Integer)

    the number of the last week in the result

Returns:

  • (Range<Aef::Weekling::Week>)

    range from self to the first following week with the given index



275
276
277
278
279
280
281
# File 'lib/aef/weekling/week.rb', line 275

def until_index(end_index)
  if end_index <= index
    self .. self.class.new(year.next, end_index)
  else
    self .. self.class.new(year, end_index)
  end
end

#wednesdayAef::Weekling::WeekDay

Returns the week’s wednesday.

Returns:



325
326
327
# File 'lib/aef/weekling/week.rb', line 325

def wednesday
  day(:wednesday)
end

#weekendArray<Aef:Weekling::WeekDay>

Returns the week’s saturday and sunday in an Array.

Returns:

  • (Array<Aef:Weekling::WeekDay>)

    the saturday and sunday of a week



360
361
362
# File 'lib/aef/weekling/week.rb', line 360

def weekend
  [saturday, sunday]
end