workpattern 0.3.6 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -277,8 +277,8 @@ module Workpattern
277
277
  #
278
278
  def clone_and_adjust_current_wp(current_wp, current_start,current_finish,clone_start,clone_finish=nil)
279
279
  clone_wp=current_wp.duplicate
280
- current_wp.adjust(current_start,current_finish)
281
- clone_finish.nil? ? clone_wp.adjust(clone_start,clone_wp.finish) : clone_wp.adjust(clone_start,clone_finish)
280
+ adjust_date_range(current_wp,current_start,current_finish)
281
+ clone_finish.nil? ? adjust_date_range(clone_wp,clone_start,clone_wp.finish) : adjust_date_range(clone_wp, clone_start,clone_finish)
282
282
  return clone_wp
283
283
  end
284
284
 
@@ -286,6 +286,11 @@ module Workpattern
286
286
  new_wp.workpattern(args[:days],args[:from_time],args[:to_time],args[:work_type])
287
287
  weeks<< new_wp
288
288
  end
289
+
290
+ def adjust_date_range(week_pattern,start_date,finish_date)
291
+ week_pattern.start = start_date
292
+ week_pattern.finish = finish_date
293
+ end
289
294
  end
290
295
  end
291
296
 
@@ -5,6 +5,7 @@ class TestWeek < MiniTest::Unit::TestCase #:nodoc:
5
5
  def setup
6
6
  start=DateTime.new(2000,1,3)
7
7
  finish=DateTime.new(2000,1,9)
8
+
8
9
  @working_week=Workpattern::Week.new(start,finish,1)
9
10
 
10
11
  @resting_week=Workpattern::Week.new(start,finish,0)
@@ -14,33 +15,46 @@ class TestWeek < MiniTest::Unit::TestCase #:nodoc:
14
15
  @pattern_week.workpattern(:weekday,Workpattern.clock(0,0),Workpattern.clock(8,59),0)
15
16
  @pattern_week.workpattern(:weekday,Workpattern.clock(12,30),Workpattern.clock(13,0),0)
16
17
  @pattern_week.workpattern(:weekday,Workpattern.clock(17,0),Workpattern.clock(23,59),0)
17
-
18
+
18
19
  end
19
20
 
20
- def test_must_diff_from_last_day_of_patterned_week
21
- #issue 15
22
- start=DateTime.new(2013,9,23,0,0)
23
- finish=DateTime.new(2013,9,26,23,59)
24
- working_week=week(start,finish,1)
25
- working_week.workpattern :all, Workpattern.clock(0,0),Workpattern.clock(8,59),0
26
- working_week.workpattern :all, Workpattern.clock(12,0),Workpattern.clock(12,59),0
27
- working_week.workpattern :all, Workpattern.clock(18,0),Workpattern.clock(23,59),0
28
21
 
29
- duration, start =working_week.diff(DateTime.civil(2013,9,26,17,0),DateTime.civil(2013,9,27,10,0))
30
-
31
- assert_equal 60, duration
32
- assert_equal DateTime.civil(2013,9,27,0,0), start
33
- end
34
-
35
22
  def test_must_create_a_working_week
36
23
  start=DateTime.new(2000,1,1,11,3)
37
24
  finish=DateTime.new(2005,12,31,16,41)
38
25
  working_week=week(start,finish,1)
39
26
  assert_equal DateTime.new(start.year,start.month,start.day), working_week.start
40
27
  assert_equal DateTime.new(finish.year,finish.month,finish.day), working_week.finish
41
- assert_equal 3156480, working_week.total#2192
28
+ assert_equal 3156480, working_week.total #2192 days
29
+ end
30
+
31
+ def test_create_working_week_of_3_concecutive_days
32
+ start=DateTime.new(2000,1,2,11,3) # Sunday
33
+ finish=DateTime.new(2000,1,4,16,41) # Tuesday
34
+ working_week=week(start,finish,1)
35
+ assert_equal DateTime.new(start.year,start.month,start.day), working_week.start
36
+ assert_equal DateTime.new(finish.year,finish.month,finish.day), working_week.finish
37
+ assert_equal 1440 * 3, working_week.total #3 days
42
38
  end
43
-
39
+
40
+ def test_create_working_week_f_to_Su
41
+ start=DateTime.new(2000,1,7,11,3) # Friday
42
+ finish=DateTime.new(2000,1,9,16,41) # Sunday
43
+ working_week=week(start,finish,1)
44
+ assert_equal DateTime.new(start.year,start.month,start.day), working_week.start
45
+ assert_equal DateTime.new(finish.year,finish.month,finish.day), working_week.finish
46
+ assert_equal 1440 * 3, working_week.total #3 days
47
+ end
48
+
49
+ def test_create_working_week_Th_to_Su
50
+ start=DateTime.new(2000,1,6,11,3) # Thursday
51
+ finish=DateTime.new(2000,1,8,16,41) # Sunday
52
+ working_week=week(start,finish,1)
53
+ assert_equal DateTime.new(start.year,start.month,start.day), working_week.start
54
+ assert_equal DateTime.new(finish.year,finish.month,finish.day), working_week.finish
55
+ assert_equal 1440 * 3, working_week.total #3 days
56
+ end
57
+
44
58
  def test_must_create_a_resting_week
45
59
  start=DateTime.new(2000,1,1,11,3)
46
60
  finish=DateTime.new(2005,12,31,16,41)
@@ -50,7 +64,7 @@ class TestWeek < MiniTest::Unit::TestCase #:nodoc:
50
64
  assert_equal 0, resting_week.total#2192
51
65
  assert_equal 0,resting_week.week_total
52
66
  end
53
-
67
+
54
68
  def test_must_duplicate_all_of_a_week
55
69
  start=DateTime.new(2000,1,1,11,3)
56
70
  finish=DateTime.new(2005,12,31,16,41)
@@ -59,7 +73,8 @@ class TestWeek < MiniTest::Unit::TestCase #:nodoc:
59
73
  assert_equal DateTime.new(start.year,start.month,start.day), new_week.start
60
74
  assert_equal DateTime.new(finish.year,finish.month,finish.day), new_week.finish
61
75
  assert_equal 3156480, new_week.total#2192
62
-
76
+ week.workpattern(:weekend,Workpattern.clock(0,0),Workpattern.clock(23,59),0)
77
+ assert_equal 3156480, new_week.total#2192
63
78
  end
64
79
 
65
80
  def test_must_set_week_pattern_correctly
@@ -79,7 +94,7 @@ class TestWeek < MiniTest::Unit::TestCase #:nodoc:
79
94
  pattern_week.workpattern(:weekday,Workpattern.clock(17,0),Workpattern.clock(23,59),0)
80
95
  assert_equal 2245, pattern_week.week_total
81
96
  end
82
-
97
+
83
98
  def test_must_set_patterns_correctly
84
99
  start=DateTime.new(2000,1,1,0,0)
85
100
  finish=DateTime.new(2005,12,31,8,59)
@@ -203,7 +218,7 @@ class TestWeek < MiniTest::Unit::TestCase #:nodoc:
203
218
  assert_equal 0, result_duration
204
219
  end
205
220
 
206
- def test_must_add_minutes_from_working_in_a_working_week_result_in_later_day
221
+ def test_must_add_minutes_from_working_in_a_pattern_week_result_in_later_day
207
222
  result_date, result_duration, midnight_flag = @pattern_week.calc(DateTime.new(2000,1,3,10,11),828)
208
223
  assert_equal DateTime.new(2000,1,5,9,1), result_date
209
224
  refute midnight_flag
@@ -397,7 +412,20 @@ class TestWeek < MiniTest::Unit::TestCase #:nodoc:
397
412
 
398
413
  ### @pattern_week centric
399
414
 
400
-
415
+ def must_diff_day_week_day_in_patterned_week
416
+ start=DateTime.new(2013,9,23,0,0)
417
+ finish=DateTime.new(2013,10,20,23,59)
418
+ working_week=week(start,finish,1)
419
+ working_week.workpattern :all, Workpattern.clock(0,0),Workpattern.clock(8,59),0
420
+ working_week.workpattern :all, Workpattern.clock(12,0),Workpattern.clock(12,59),0
421
+ working_week.workpattern :all, Workpattern.clock(18,0),Workpattern.clock(23,59),0
422
+
423
+ duration, start =working_week.diff(DateTime.civil(2013,10,3,16,0),DateTime.civil(2013,10,15,12,30))
424
+
425
+ assert_equal 5640, duration
426
+ assert_equal DateTime.civil(2013,10,15,12,30), start
427
+
428
+ end
401
429
  def test_must_calculate_difference_between_dates_in_working_week
402
430
  late_date=DateTime.new(2000,1,6,9,32)
403
431
  early_date=DateTime.new(2000,1,6,8,20)
@@ -421,6 +449,51 @@ class TestWeek < MiniTest::Unit::TestCase #:nodoc:
421
449
  assert_equal 1, result_dur
422
450
  assert_equal late_date, result_date
423
451
  end
452
+
453
+ def test_must_diff_from_last_day_of_patterned_week
454
+ #issue 15
455
+ start=DateTime.new(2013,9,23,0,0)
456
+ finish=DateTime.new(2013,9,26,23,59)
457
+ working_week=week(start,finish,1)
458
+ working_week.workpattern :all, Workpattern.clock(0,0),Workpattern.clock(8,59),0
459
+ working_week.workpattern :all, Workpattern.clock(12,0),Workpattern.clock(12,59),0
460
+ working_week.workpattern :all, Workpattern.clock(18,0),Workpattern.clock(23,59),0
461
+
462
+ duration, start =working_week.diff(DateTime.civil(2013,9,26,17,0),DateTime.civil(2013,9,27,10,0))
463
+
464
+ assert_equal 60, duration
465
+ assert_equal DateTime.civil(2013,9,27,0,0), start
466
+ end
467
+
468
+ def test_must_diff_long_distances_beyond_end_of_patterned_week
469
+ start=DateTime.new(2013,9,23,0,0)
470
+ finish=DateTime.new(2013,10,20,23,59)
471
+ working_week=week(start,finish,1)
472
+ working_week.workpattern :all, Workpattern.clock(0,0),Workpattern.clock(8,59),0
473
+ working_week.workpattern :all, Workpattern.clock(12,0),Workpattern.clock(12,59),0
474
+ working_week.workpattern :all, Workpattern.clock(18,0),Workpattern.clock(23,59),0
475
+
476
+ duration, start =working_week.diff(DateTime.civil(2013,9,26,17,0),DateTime.civil(2018,9,27,10,0))
477
+
478
+ assert_equal 11580, duration
479
+ assert_equal DateTime.civil(2013,10,21,0,0), start
480
+
481
+ end
482
+
483
+ def test_must_diff_long_distances_within_patterned_week
484
+ start=DateTime.new(2013,9,23,0,0)
485
+ finish=DateTime.new(2013,10,20,23,59)
486
+ working_week=week(start,finish,1)
487
+ working_week.workpattern :all, Workpattern.clock(0,0),Workpattern.clock(8,59),0
488
+ working_week.workpattern :all, Workpattern.clock(12,0),Workpattern.clock(12,59),0
489
+ working_week.workpattern :all, Workpattern.clock(18,0),Workpattern.clock(23,59),0
490
+
491
+ duration, start =working_week.diff(DateTime.civil(2013,9,26,17,0),DateTime.civil(2013,10,15,10,0))
492
+
493
+ assert_equal 8760, duration
494
+ assert_equal DateTime.civil(2013,10,15,10,0), start
495
+
496
+ end
424
497
 
425
498
  private
426
499
 
@@ -432,4 +505,3 @@ class TestWeek < MiniTest::Unit::TestCase #:nodoc:
432
505
  return Workpattern.clock(hour,min)
433
506
  end
434
507
  end
435
-
metadata CHANGED
@@ -1,27 +1,27 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: workpattern
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.6
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Barrie Callender
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2014-03-25 00:00:00.000000000 Z
11
+ date: 2014-05-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ~>
18
18
  - !ruby/object:Gem::Version
19
19
  version: 0.9.2
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ~>
25
25
  - !ruby/object:Gem::Version
26
26
  version: 0.9.2
27
27
  description: Workpattern performs date calculations that take into account working
@@ -32,8 +32,8 @@ executables: []
32
32
  extensions: []
33
33
  extra_rdoc_files: []
34
34
  files:
35
- - ".gitignore"
36
- - ".travis.yml"
35
+ - .gitignore
36
+ - .travis.yml
37
37
  - CHANGELOG
38
38
  - Gemfile
39
39
  - README.md
@@ -41,8 +41,6 @@ files:
41
41
  - config/website.yml
42
42
  - lib/workpattern.rb
43
43
  - lib/workpattern/clock.rb
44
- - lib/workpattern/day.rb
45
- - lib/workpattern/hour.rb
46
44
  - lib/workpattern/utility/base.rb
47
45
  - lib/workpattern/version.rb
48
46
  - lib/workpattern/week.rb
@@ -52,9 +50,7 @@ files:
52
50
  - script/generate
53
51
  - script/txt2html
54
52
  - test/test_clock.rb
55
- - test/test_day.rb
56
53
  - test/test_helper.rb
57
- - test/test_hour.rb
58
54
  - test/test_week.rb
59
55
  - test/test_workpattern.rb
60
56
  - test/test_workpattern_module.rb
@@ -69,12 +65,12 @@ require_paths:
69
65
  - lib
70
66
  required_ruby_version: !ruby/object:Gem::Requirement
71
67
  requirements:
72
- - - ">="
68
+ - - ! '>='
73
69
  - !ruby/object:Gem::Version
74
70
  version: '0'
75
71
  required_rubygems_version: !ruby/object:Gem::Requirement
76
72
  requirements:
77
- - - ">="
73
+ - - ! '>='
78
74
  - !ruby/object:Gem::Version
79
75
  version: '0'
80
76
  requirements: []
@@ -1,343 +0,0 @@
1
- module Workpattern
2
-
3
- # @author Barrie Callender
4
- # @!attribute values
5
- # @return [Array] each hour of the day
6
- # @!attribute hours
7
- # @return [Integer] number of hours in the day
8
- # @!attribute first_hour
9
- # @return [Integer] first working hour in the day
10
- # @!attribute first_min
11
- # @return [Integer] first working minute in first working hour in the day
12
- # @!attribute last_hour
13
- # @return [Integer] last working hour in the day
14
- # @!attribute last_min
15
- # @return [Integer] last working minute in last working hour in the day
16
- # @!attribute total
17
- # @return [Integer] total number of minutes in the day
18
- #
19
- # Represents the 24 hours of a day.
20
- #
21
- # @since 0.2.0
22
- # @todo implement a day with different number of hours in it to support daylight saving
23
- #
24
- class Day
25
- include Workpattern::Utility
26
- attr_accessor :values, :hours, :first_hour, :first_min, :last_hour, :last_min, :total
27
-
28
- # The new <tt>Day</tt> object can be created as either working or resting.
29
- #
30
- # @param [Integer] type is working (1) or resting (0)
31
- #
32
- def initialize(type=1)
33
- @hours=24
34
- hour=WORKING_HOUR if type==1
35
- hour=RESTING_HOUR if type==0
36
- @values=Array.new(@hours) {|index| hour }
37
- end
38
-
39
- # Creates a duplicate of the current <tt>Day</tt> instance.
40
- #
41
- # @return [Day]
42
- #
43
- def duplicate
44
- duplicate_day = Day.new()
45
- duplicate_values=Array.new(self.values.size)
46
- self.values.each_index {|index|
47
- duplicate_values[index]=self.values[index]
48
- }
49
- duplicate_day.values=duplicate_values
50
- duplicate_day.hours = self.hours
51
- duplicate_day.first_hour=self.first_hour
52
- duplicate_day.first_min=self.first_min
53
- duplicate_day.last_hour=self.last_hour
54
- duplicate_day.last_min=self.last_min
55
- duplicate_day.total = self.total
56
- duplicate_day.refresh
57
- return duplicate_day
58
- end
59
-
60
- # Recalculates characteristics for this day
61
- # no longer required as calculating individually is faster
62
- #
63
- def refresh
64
-
65
- end
66
-
67
- # Sets all minutes in a date range to be working or resting.
68
- #
69
- # @param [(#hour,#min)] start_time is the start of the range to set
70
- # @param [(#hour, #min)] finish_time is the finish of the range to be set
71
- # @param [Integer] type is either working (1) or resting (0)
72
- #
73
- def workpattern(start_time,finish_time,type)
74
-
75
- if start_time.hour==finish_time.hour
76
- self.values[start_time.hour]=self.values[start_time.hour].wp_workpattern(start_time.min,finish_time.min,type)
77
- else
78
- test_hour=start_time.hour
79
- self.values[test_hour]=self.values[test_hour].wp_workpattern(start_time.min,59,type)
80
-
81
- while ((test_hour+1)<finish_time.hour)
82
- test_hour+=1
83
- self.values[test_hour]=self.values[test_hour].wp_workpattern(0,59,type)
84
- end
85
-
86
- self.values[finish_time.hour]=self.values[finish_time.hour].wp_workpattern(0,finish_time.min,type)
87
- end
88
-
89
- end
90
-
91
- # Calculates the result of adding <tt>duration</tt> to
92
- # <tt>time</tt>. The <tt>duration</tt> can be negative in
93
- # which case it subtracts from <tt>time</tt>.
94
- #
95
- # An addition where there are less working minutes left in
96
- # the day than are being added will result in the time
97
- # returned being 00:00 on the following day.
98
- #
99
- # A subtraction where there are less working minutes left in
100
- # the day than are being added will result in the time
101
- # returned being the previous day with the <tt>midnight</tt> flag set to true.
102
- #
103
- # @param [DateTime] time when the calculation starts from
104
- # @param [Integer] duration is the number of minutes to add or subtract if it is negative
105
- # @param [Boolean] midnight is a flag used in subtraction to pretend the time is actually midnight
106
- # @return [DateTime,Integer,Boolean] Calculated time along with any remaining duration and the midnight flag
107
- #
108
- def calc(time,duration,midnight=false)
109
-
110
- if (duration<0)
111
- return subtract(time,duration, midnight)
112
- elsif (duration>0)
113
- return add(time,duration)
114
- else
115
- return time,duration, false
116
- end
117
-
118
- end
119
-
120
- # Returns true if the given minute is working and false if it is resting
121
- #
122
- # @param [(#hour, #min)] start is the time in the day to inspect
123
- # @return [Boolean] true if the time is working and false if it is resting
124
- #
125
- def working?(start)
126
- return true if minutes(start.hour,start.min,start.hour,start.min)==1
127
- return false
128
- end
129
-
130
- # Returns the difference in working minutes between two times.
131
- #
132
- # @param [(#hour, #min)] start start time in the range
133
- # @param [(#hour, #min)] finish finish time in the range
134
- # @return [Integer] number of working minutes
135
- #
136
- def diff(start,finish)
137
- start,finish=finish,start if ((start <=> finish))==1
138
- # calculate to end of hour
139
- #
140
- if (start.jd==finish.jd) # same day
141
- duration=minutes(start.hour,start.min,finish.hour, finish.min)
142
- duration -=1 if working?(finish)
143
- start=finish
144
- else
145
- duration=minutes(start.hour,start.min,23, 59)
146
- start=start+((23-start.hour)*HOUR) +((60-start.min)*MINUTE)
147
- end
148
- return duration, start
149
- end
150
-
151
- # Returns the total number of minutes between two times.
152
- #
153
- # @param [Integer] start_hour first hour in range
154
- # @param [Integer] start_min first minute of first hour in range
155
- # @param [Integer] finish_hour last hour in range
156
- # @param [Integer] finish_min last minute of last hour in range
157
- # @return [Integer] minutes between supplied hours and minutes
158
- #
159
- # @todo can this method and #diff method be combined?
160
- #
161
- def minutes(start_hour,start_min,finish_hour,finish_min)
162
-
163
- if (start_hour > finish_hour) || ((finish_hour==start_hour) && (start_min > finish_min))
164
- start_hour,start_min,finish_hour,finish_min=finish_hour,finish_min,start_hour,finish_min
165
- end
166
-
167
- if (start_hour==finish_hour)
168
- retval=self.values[start_hour].wp_minutes(start_min,finish_min)
169
- else
170
-
171
- retval=self.values[start_hour].wp_minutes(start_min,59)
172
- while (start_hour+1<finish_hour)
173
- retval+=self.values[start_hour+1].wp_total
174
- start_hour+=1
175
- end
176
- retval+=self.values[finish_hour].wp_minutes(0,finish_min)
177
- end
178
-
179
- return retval
180
- end
181
-
182
-
183
- def first_hour
184
- 0.upto(self.hours-1) do |index|
185
- return index if self.values[index].wp_total!=0
186
- end
187
- return nil
188
- end
189
-
190
- def first_min
191
- 0.upto(self.hours-1) do |index|
192
- return self.values[index].wp_first if !self.values[index].wp_first.nil?
193
- end
194
- return nil
195
- end
196
-
197
- def last_hour
198
- (self.hours-1).downto(0) do |index|
199
- return index if self.values[index].wp_total!=0
200
- end
201
- return nil
202
- end
203
-
204
- def last_min
205
- (self.hours-1).downto(0) do |index|
206
- return self.values[index].wp_last if self.values[index].wp_total!=0
207
- end
208
- return nil
209
- end
210
-
211
- def total
212
- total_minutes=0
213
- 0.upto(self.hours-1) do |index|
214
- total_minutes+=self.values[index].wp_total
215
- end
216
- return total_minutes
217
- end
218
- private
219
-
220
-
221
- # Returns the first working minute as a <tt>DateTime</tt> or <tt>oo:oo</tt>
222
- # when there is no working minutes in the day. Used by the <tt>#subtract</tt> method
223
- #
224
- # @param [DateTime] time day for which the first working time is sought.
225
- # @return [DateTime] the first working time of the day
226
- #
227
- def first_working_minute(time)
228
- if self.first_hour.nil?
229
- return time - (HOUR*time.hour) - (MINUTE*time.min)
230
- else
231
- time = time - HOUR * (time.hour - self.first_hour)
232
- time = time - MINUTE * (time.min - self.first_min )
233
- return time
234
- end
235
- end
236
-
237
- # Handles the subtraction of a duration from a time in the day.
238
- #
239
- # @param [DateTime] time when the subtraction starts from
240
- # @param [Integer] duration is the number of minutes to subtract from the <tt>time</tt>
241
- # @param [Boolean] midnight is a flag used in subtraction to pretend the time is actually midnight
242
- # @return [DateTime,Integer,Boolean] Calculated time along with any remaining duration and the midnight flag
243
- #
244
- def subtract(time,duration,midnight=false)
245
- if (time.hour==0 && time.min==0)
246
- if midnight
247
- duration+=minutes(23,59,23,59)
248
- time=time+(HOUR*23)+(MINUTE*59)
249
- return calc(time,duration)
250
- else
251
- return time.prev_day, duration,true
252
- end
253
- elsif (time.hour==self.first_hour && time.min==self.first_min)
254
- time=time-(HOUR*self.first_hour) - (MINUTE*self.first_min)
255
- return time.prev_day, duration, true
256
- elsif (time.min>0)
257
- available_minutes=minutes(0,0,time.hour,time.min-1)
258
- else
259
- available_minutes=minutes(0,0,time.hour-1,59)
260
- end
261
- if ((duration+available_minutes)<0) # not enough minutes in the day
262
- time = midnight_before(time.prev_day)
263
- duration = duration + available_minutes
264
- return time, duration, true
265
- elsif ((duration+available_minutes)==0)
266
- duration=0
267
- time=first_working_minute(time)
268
- else
269
- minutes_this_hour=self.values[time.hour].wp_minutes(0,time.min-1)
270
- this_hour=time.hour
271
- until (duration==0)
272
- if (minutes_this_hour<duration.abs)
273
- duration+=minutes_this_hour
274
- time = time - (MINUTE*time.min) - HOUR
275
- this_hour-=1
276
- minutes_this_hour=self.values[this_hour].wp_total
277
- else
278
- next_hour=(time.min==0)
279
- time,duration=self.values[this_hour].wp_calc(time,duration, next_hour)
280
- end
281
- end
282
- end
283
- return time,duration, false
284
- end
285
-
286
- # Returns the result of adding <tt>duration</tt> to the given <tt>time</tt>
287
- # When there are not enough minutes in the day it returns the date
288
- # for the start of the following day.
289
- #
290
- # @param [DateTime] time when the calculation starts from
291
- # @param [Integer] duration is the number of minutes to add
292
- # @return [DateTime,Integer] Calculated time along with any remaining duration
293
- #
294
- def add(time,duration)
295
- available_minutes=minutes(time.hour,time.min,self.hours-1,59)
296
- if ((duration-available_minutes)>0) # not enough minutes left in the day
297
-
298
- result_date= time.next_day - (HOUR*time.hour) - (MINUTE*time.min)
299
- duration = duration - available_minutes
300
- else
301
- total=self.values[time.hour].wp_minutes(time.min,59)
302
- if (total==duration) # this hour satisfies
303
- result_date=time - (MINUTE*time.min) + (MINUTE*self.values[time.hour].wp_last) + MINUTE
304
- duration = 0
305
- else
306
- result_date = time
307
- until (duration==0)
308
- if (total<duration)
309
- duration-=total
310
- result_date=result_date + HOUR - (MINUTE*result_date.min)
311
- else
312
- result_date,duration=self.values[result_date.hour].wp_calc(result_date,duration)
313
- end
314
- total=self.values[result_date.hour].wp_total
315
- end
316
- end
317
- end
318
- return result_date,duration, false
319
- end
320
-
321
- # Returns the start of the next hour.
322
- #
323
- # The next hour could be the start of the following day.
324
- #
325
- # @param [DateTime] start is the <tt>DateTime</tt> for which the following hour is required.
326
- # @return [DateTime] the start of the next hour following the <tt>DateTime</tt> supplied
327
- #
328
- def next_hour(start)
329
- return start+HOUR-(start.min*MINUTE)
330
- end
331
-
332
- # Returns the number of working minutes left in the current hour
333
- #
334
- # @param [DateTime] start is the <tt>DateTime</tt> for which the remaining working minutes
335
- # in the hour are required
336
- # @return [Integer] number of remaining working minutes
337
- #
338
- def minutes_left_in_hour(start)
339
- return self.values[start.hour].wp_diff(start.min,60)
340
- end
341
-
342
- end
343
- end