Class: TaskJuggler::WorkingHours

Inherits:
Object
  • Object
show all
Defined in:
lib/taskjuggler/WorkingHours.rb

Overview

Class to store the working hours for each day of the week. The working hours are stored as Arrays of Integer intervals for each day of the week. A day off is modelled as empty Array for that week day. The start end end times of each working period are stored as seconds after midnight.

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(arg1 = nil, startDate = nil, endDate = nil, timeZone = nil) ⇒ WorkingHours

Create a new WorkingHours object. The method accepts a reference to an existing WorkingHours object in wh. When it’s present, the new object will be a deep copy of the given object. The Scoreboard object is not deep copied. It will be copied on write.



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
66
67
68
69
70
71
72
# File 'lib/taskjuggler/WorkingHours.rb', line 32

def initialize(arg1 = nil, startDate = nil, endDate = nil, timeZone = nil)
  # One entry for every day of the week. Sunday === 0.
  @days = Array.new(7, [])
  @scoreboard = nil

  if arg1.is_a?(WorkingHours)
    # Create a copy of the passed WorkingHours object.
    wh = arg1
    @timezone = wh.timezone
    7.times do |day|
      hours = []
      wh.days[day].each do |hrs|
        hours << hrs.dup
      end
      setWorkingHours(day, hours)
    end
    @startDate = wh.startDate
    @endDate = wh.endDate
    @slotDuration = wh.slotDuration
    # Make sure the copied scoreboard has been created, so we can share it
    # copy-on-write.
    wh.onShift?(0)
    @scoreboard = wh.scoreboard
  else
    slotDuration = arg1
    if arg1.nil? || startDate.nil? || endDate.nil?
      raise "You must supply values for slotDuration, start and end dates"
    end
    @startDate = startDate
    @endDate = endDate
    @slotDuration = slotDuration

    # Create a new object with default working hours.
    @timezone = timeZone
    # Set the default working hours. Monday to Friday 9am - 5pm.
    # Saturday and Sunday are days off.
    1.upto(5) do |day|
      @days[day] = [ [ 9 * 60 * 60, 17 * 60 * 60 ] ]
    end
  end
end

Instance Attribute Details

#daysObject (readonly)

Returns the value of attribute days.



25
26
27
# File 'lib/taskjuggler/WorkingHours.rb', line 25

def days
  @days
end

#endDateObject (readonly)

Returns the value of attribute endDate.



25
26
27
# File 'lib/taskjuggler/WorkingHours.rb', line 25

def endDate
  @endDate
end

#scoreboardObject (readonly)

Returns the value of attribute scoreboard.



25
26
27
# File 'lib/taskjuggler/WorkingHours.rb', line 25

def scoreboard
  @scoreboard
end

#slotDurationObject (readonly)

Returns the value of attribute slotDuration.



25
26
27
# File 'lib/taskjuggler/WorkingHours.rb', line 25

def slotDuration
  @slotDuration
end

#startDateObject (readonly)

Returns the value of attribute startDate.



25
26
27
# File 'lib/taskjuggler/WorkingHours.rb', line 25

def startDate
  @startDate
end

#timezoneObject

Returns the value of attribute timezone.



25
26
27
# File 'lib/taskjuggler/WorkingHours.rb', line 25

def timezone
  @timezone
end

Instance Method Details

#==(wh) ⇒ Object

Return true of the given WorkingHours object wh is identical to this object.



84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/taskjuggler/WorkingHours.rb', line 84

def ==(wh)
  return false if wh.nil? || @timezone != wh.timezone ||
         @startDate != wh.startDate ||
         @endDate != wh.endDate ||
         @slotDuration != wh.slotDuration

  7.times do |d|
    return false if @days[d].length != wh.days[d].length
    # Check all working hour intervals
    @days[d].length.times do |i|
      return false if @days[d][i][0] != wh.days[d][i][0] ||
                      @days[d][i][1] != wh.days[d][i][1]
    end
  end
  true
end

#deep_cloneObject

Since we want to share the scoreboard among instances with identical working hours, we need to prevent the scoreboard from being deep cloned. Calling the constructor with self in a re-defined deep_clone method will do just that.



78
79
80
# File 'lib/taskjuggler/WorkingHours.rb', line 78

def deep_clone
  WorkingHours.new(self)
end

#getWorkingHours(dayOfWeek) ⇒ Object

Return the working hour intervals for a given day of the week. dayOfWeek must 0 for Sunday, 1 for Monday and so on. The result is an Array that contains Arrays of 2 Integers.



137
138
139
# File 'lib/taskjuggler/WorkingHours.rb', line 137

def getWorkingHours(dayOfWeek)
  @days[dayOfWeek]
end

#onShift?(arg) ⇒ Boolean

Return true if arg is within the defined working hours. arg can be a TjTime object or a global scoreboard index.

Returns:

  • (Boolean)


143
144
145
146
147
148
149
150
151
# File 'lib/taskjuggler/WorkingHours.rb', line 143

def onShift?(arg)
  initScoreboard unless @scoreboard

  if arg.is_a?(TjTime)
    @scoreboard.get(arg)
  else
    @scoreboard[arg]
  end
end

#setWorkingHours(dayOfWeek, intervals) ⇒ Object

Set the working hours for a given week day. dayOfWeek must be 0 for Sunday, 1 for Monday and so on. intervals must be an Array that contains an Array with 2 Integers for each working period. Each value specifies the time of day as minutes after midnight. The first value is the start time of the interval, the second the end time.



106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
# File 'lib/taskjuggler/WorkingHours.rb', line 106

def setWorkingHours(dayOfWeek, intervals)
  # Changing the working hours requires the score board to be regenerated.
  @scoreboard = nil

  # Legal values range from 0 Sunday to 6 Saturday.
  if dayOfWeek < 0 || dayOfWeek > 6
    raise "dayOfWeek out of range: #{dayOfWeek}"
  end
  intervals.each do |iv|
    if iv[0] < 0 || iv[0] > 24 * 60 * 60 ||
       iv[1] < 0 || iv[1] > 24 * 60 * 60
      raise "Time interval has illegal values: " +
            "#{time_to_s(iv[0])} - #{time_to_s(iv[1])}"
    end
    if iv[0] >= iv[1]
      raise "Interval end time must be larger than start time"
    end
  end
  @days[dayOfWeek] = intervals
end

#timeOff?(interval) ⇒ Boolean

Return true only if all slots in the interval are offhour slots.

Returns:

  • (Boolean)


154
155
156
157
158
159
160
161
162
163
164
# File 'lib/taskjuggler/WorkingHours.rb', line 154

def timeOff?(interval)
  initScoreboard unless @scoreboard

  startIdx = @scoreboard.dateToIdx(interval.start)
  endIdx = @scoreboard.dateToIdx(interval.end)

  startIdx.upto(endIdx - 1) do |i|
    return false if @scoreboard[i]
  end
  true
end

#to_sObject

Returns the time interval settings for each day in a human readable form.



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
# File 'lib/taskjuggler/WorkingHours.rb', line 178

def to_s
  dayNames = %w( Sun Mon Tue Wed Thu Fri Sat )
  str = ''
  7.times do |day|
    str += "#{dayNames[day]}: "
    if @days[day].empty?
      str += "off"
      str += "\n" if day < 6
      next
    end
    first = true
    @days[day].each do |iv|
      if first
        first = false
      else
        str += ', '
      end
      str += "#{time_to_s(iv[0])} - #{time_to_s(iv[0])}"
    end
    str += "\n" if day < 6
  end
  str
end

#weeklyWorkingHoursObject

Return the number of working hours per week.



167
168
169
170
171
172
173
174
175
# File 'lib/taskjuggler/WorkingHours.rb', line 167

def weeklyWorkingHours
  seconds = 0
  @days.each do |day|
    day.each do |from, to|
       seconds += (to - from)
    end
  end
  seconds / (60 * 60)
end