workpattern 0.3.4 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/.gitignore +8 -4
- data/.travis.yml +18 -3
- data/CHANGELOG.md +88 -0
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +19 -4
- data/LICENSE.txt +21 -0
- data/README.md +56 -80
- data/Rakefile +9 -0
- data/lib/workpattern.rb +31 -91
- data/lib/workpattern/clock.rb +21 -20
- data/lib/workpattern/constants.rb +72 -0
- data/lib/workpattern/day.rb +211 -290
- data/lib/workpattern/version.rb +2 -4
- data/lib/workpattern/week.rb +239 -321
- data/lib/workpattern/week_pattern.rb +144 -0
- data/lib/workpattern/workpattern.rb +156 -187
- data/workpattern.gemspec +32 -18
- metadata +40 -28
- data/CHANGELOG +0 -35
- data/config/website.yml +0 -2
- data/lib/workpattern/hour.rb +0 -209
- data/lib/workpattern/utility/base.rb +0 -32
- data/test/test_clock.rb +0 -31
- data/test/test_day.rb +0 -522
- data/test/test_helper.rb +0 -3
- data/test/test_hour.rb +0 -389
- data/test/test_week.rb +0 -362
- data/test/test_workpattern.rb +0 -276
- data/test/test_workpattern_module.rb +0 -93
data/lib/workpattern/version.rb
CHANGED
data/lib/workpattern/week.rb
CHANGED
@@ -1,363 +1,281 @@
|
|
1
1
|
module Workpattern
|
2
|
-
|
3
|
-
#
|
4
|
-
#
|
5
|
-
# @return [Array] each day of the week
|
6
|
-
# @!attribute days
|
7
|
-
# @return [Integer] number of days in the week
|
8
|
-
# @!attribute start
|
9
|
-
# @return [DateTime] first date in the range
|
10
|
-
# @!attribute finish
|
11
|
-
# @return [DateTime] last date in the range
|
12
|
-
# @!attribute week_total
|
13
|
-
# @return [Integer] total number of minutes in a week
|
14
|
-
# @!attribute total
|
15
|
-
# @return [Integer] total number of minutes in the range
|
16
|
-
#
|
17
|
-
# Represents working and resting periods for each day in a week for a specified date range.
|
2
|
+
# The representation of a week might not be obvious so I am writing about it
|
3
|
+
# here. It will also help me if I ever need to come back to this in the
|
4
|
+
# future.
|
18
5
|
#
|
19
|
-
#
|
6
|
+
# Each day is represented by a binary number where a 1 represents a working
|
7
|
+
# minute and a 0 represents a resting minute.
|
20
8
|
#
|
9
|
+
# @private
|
21
10
|
class Week
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
hours_in_days_in_week=[24,24,24,24,24,24,24]
|
34
|
-
@days=hours_in_days_in_week.size
|
35
|
-
@values=Array.new(7) {|index| Day.new(type)}
|
36
|
-
@start=DateTime.new(start.year,start.month,start.day)
|
37
|
-
@finish=DateTime.new(finish.year,finish.month,finish.day)
|
38
|
-
|
39
|
-
set_attributes
|
11
|
+
attr_accessor :hours_per_day, :start, :finish, :days
|
12
|
+
attr_writer :week_total, :total
|
13
|
+
|
14
|
+
def initialize(start, finish, type = WORK_TYPE, hours_per_day = HOURS_IN_DAY)
|
15
|
+
@hours_per_day = hours_per_day
|
16
|
+
@start = Time.gm(start.year, start.month, start.day)
|
17
|
+
@finish = Time.gm(finish.year, finish.month, finish.day)
|
18
|
+
@days = Array.new(LAST_DAY_OF_WEEK)
|
19
|
+
FIRST_DAY_OF_WEEK.upto(LAST_DAY_OF_WEEK) do |i|
|
20
|
+
@days[i] = Day.new(hours_per_day, type)
|
21
|
+
end
|
40
22
|
end
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
def duplicate()
|
47
|
-
duplicate_week=Week.new(@start,@finish)
|
48
|
-
duplicate_values=Array.new(@values.size)
|
49
|
-
@values.each_index {|index|
|
50
|
-
duplicate_values[index]=@values[index].duplicate
|
51
|
-
}
|
52
|
-
duplicate_week.values=duplicate_values
|
53
|
-
duplicate_week.days=@days
|
54
|
-
duplicate_week.start=@start
|
55
|
-
duplicate_week.finish=@finish
|
56
|
-
duplicate_week.week_total=@week_total
|
57
|
-
duplicate_week.total=@total
|
58
|
-
duplicate_week.refresh
|
59
|
-
return duplicate_week
|
23
|
+
|
24
|
+
def <=>(other)
|
25
|
+
return -1 if start < other.start
|
26
|
+
return 0 if start == other.start
|
27
|
+
1
|
60
28
|
end
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
#
|
65
|
-
def refresh
|
66
|
-
set_attributes
|
29
|
+
|
30
|
+
def week_total
|
31
|
+
elapsed_days > 6 ? full_week_working_minutes : part_week_total_minutes
|
67
32
|
end
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
#
|
72
|
-
# @param [DateTime] start is the new starting date for the <tt>Week</tt>
|
73
|
-
# @param [DateTime] finish is the new finish date for the <tt>Week</tt>
|
74
|
-
#
|
75
|
-
def adjust(start,finish)
|
76
|
-
@start=DateTime.new(start.year,start.month,start.day)
|
77
|
-
@finish=DateTime.new(finish.year,finish.month,finish.day)
|
78
|
-
refresh
|
33
|
+
|
34
|
+
def total
|
35
|
+
elapsed_days < 8 ? week_total : range_total
|
79
36
|
end
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
def workpattern(days,from_time,to_time,type)
|
90
|
-
DAYNAMES[days].each {|day| @values[day].workpattern(from_time,to_time,type)}
|
91
|
-
refresh
|
37
|
+
|
38
|
+
def workpattern(days, from_time, to_time, type)
|
39
|
+
DAYNAMES[days].each do |day|
|
40
|
+
if type == WORK_TYPE
|
41
|
+
@days[day].set_working(from_time, to_time)
|
42
|
+
else
|
43
|
+
@days[day].set_resting(from_time, to_time)
|
44
|
+
end
|
45
|
+
end
|
92
46
|
end
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
return add(start,duration) if duration > 0
|
103
|
-
return subtract(@start,duration, midnight) if (@total==0) && (duration <0)
|
104
|
-
return subtract(start,duration, midnight) if duration <0
|
47
|
+
|
48
|
+
def duplicate
|
49
|
+
duplicate_week = Week.new(@start, @finish)
|
50
|
+
FIRST_DAY_OF_WEEK.upto(LAST_DAY_OF_WEEK) do |i|
|
51
|
+
duplicate_week.days[i] = @days[i].clone
|
52
|
+
duplicate_week.days[i].hours_per_day = @days[i].hours_per_day
|
53
|
+
duplicate_week.days[i].pattern = @days[i].pattern
|
54
|
+
end
|
55
|
+
duplicate_week
|
105
56
|
end
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
return 0
|
116
|
-
else
|
117
|
-
return 1
|
118
|
-
end
|
57
|
+
|
58
|
+
def calc(a_date, a_duration, a_day = SAME_DAY)
|
59
|
+
if a_duration == 0
|
60
|
+
return a_date, a_duration
|
61
|
+
elsif a_duration > 0
|
62
|
+
return add(a_date, a_duration)
|
63
|
+
else
|
64
|
+
subtract(a_date, a_duration, a_day)
|
65
|
+
end
|
119
66
|
end
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
# calculate to end of day
|
139
|
-
#
|
140
|
-
if (start.jd==finish.jd) # same day
|
141
|
-
duration, start=@values[start.wday].diff(start,finish)
|
142
|
-
elsif (finish.jd<=@finish.jd) #within this week
|
143
|
-
duration, start=diff_detail(start,finish,finish)
|
144
|
-
else # after this week
|
145
|
-
duration, start=diff_detail(start,finish,@finish)
|
67
|
+
|
68
|
+
def working?(time)
|
69
|
+
@days[time.wday].working?(time.hour, time.min)
|
70
|
+
end
|
71
|
+
|
72
|
+
def resting?(time)
|
73
|
+
@days[time.wday].resting?(time.hour, time.min)
|
74
|
+
end
|
75
|
+
|
76
|
+
def diff(start_date, finish_date)
|
77
|
+
if start_date > finish_date
|
78
|
+
start_date, finish_date = finish_date, start_date
|
79
|
+
end
|
80
|
+
|
81
|
+
if jd(start_date) == jd(finish_date)
|
82
|
+
return diff_in_same_day(start_date, finish_date)
|
83
|
+
else
|
84
|
+
return diff_in_same_weekpattern(start_date, finish_date)
|
146
85
|
end
|
147
|
-
return duration, start
|
148
86
|
end
|
149
87
|
|
150
88
|
private
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
89
|
+
|
90
|
+
def elapsed_days
|
91
|
+
(finish - start).to_i / DAY + 1
|
92
|
+
end
|
93
|
+
|
94
|
+
def full_week_working_minutes
|
95
|
+
minutes_in_day_range FIRST_DAY_OF_WEEK, LAST_DAY_OF_WEEK
|
96
|
+
end
|
97
|
+
|
98
|
+
def part_week_total_minutes
|
99
|
+
start.wday <= finish.wday ? no_rollover_minutes : rollover_minutes
|
100
|
+
end
|
101
|
+
|
102
|
+
def no_rollover_minutes
|
103
|
+
minutes_in_day_range(start.wday, finish.wday)
|
104
|
+
end
|
105
|
+
|
106
|
+
def rollover_minutes
|
107
|
+
minutes_to_first_saturday + minutes_to_finish_day
|
108
|
+
end
|
109
|
+
|
110
|
+
def range_total
|
111
|
+
total_days = elapsed_days
|
112
|
+
|
113
|
+
sum = minutes_to_first_saturday
|
114
|
+
total_days -= (7 - start.wday)
|
115
|
+
|
116
|
+
sum += minutes_to_finish_day
|
117
|
+
total_days -= (finish.wday + 1)
|
118
|
+
|
119
|
+
sum += week_total * total_days / 7
|
120
|
+
sum
|
121
|
+
end
|
122
|
+
|
123
|
+
def minutes_to_first_saturday
|
124
|
+
minutes_in_day_range(start.wday, LAST_DAY_OF_WEEK)
|
125
|
+
end
|
126
|
+
|
127
|
+
def minutes_to_finish_day
|
128
|
+
minutes_in_day_range(FIRST_DAY_OF_WEEK, finish.wday)
|
129
|
+
end
|
130
|
+
|
131
|
+
def minutes_in_day_range(first, last)
|
132
|
+
@days[first..last].inject(0) { |sum, day| sum + day.working_minutes }
|
133
|
+
end
|
134
|
+
|
135
|
+
def add(a_date, a_duration)
|
136
|
+
|
137
|
+
r_date, r_duration = add_to_end_of_day(a_date, a_duration)
|
138
|
+
|
139
|
+
r_date, r_duration = add_to_finish_day r_date, r_duration
|
140
|
+
r_date, r_duration = add_full_weeks r_date, r_duration
|
141
|
+
r_date, r_duration = add_remaining_days r_date, r_duration
|
142
|
+
[r_date, r_duration, false]
|
143
|
+
end
|
144
|
+
|
145
|
+
def add_to_end_of_day(a_date, a_duration)
|
146
|
+
r_date, r_duration, r_day = @days[a_date.wday].calc(a_date,a_duration)
|
147
|
+
|
148
|
+
if r_day == NEXT_DAY
|
149
|
+
r_date = start_of_next_day(r_date)
|
150
|
+
|
170
151
|
end
|
152
|
+
|
153
|
+
[r_date, r_duration]
|
171
154
|
end
|
172
|
-
|
173
|
-
|
174
|
-
|
175
|
-
|
176
|
-
|
177
|
-
|
178
|
-
|
179
|
-
def total_hours(start,finish)
|
180
|
-
total=0
|
181
|
-
start.upto(finish) {|day|
|
182
|
-
total+=@values[day].total
|
183
|
-
}
|
184
|
-
return total
|
155
|
+
|
156
|
+
def add_to_finish_day(a_date, a_duration)
|
157
|
+
while ( a_duration != 0) && (a_date.wday != next_day(self.finish).wday) && (jd(a_date) <= jd(self.finish))
|
158
|
+
a_date, a_duration = add_to_end_of_day(a_date,a_duration)
|
159
|
+
end
|
160
|
+
|
161
|
+
[a_date, a_duration]
|
185
162
|
end
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
191
|
-
|
192
|
-
# @param [Integer] duration minutes to add
|
193
|
-
# @return [DateTime, Integer, Boolean] the calculated date, remaining minutes and flag used for subtraction
|
194
|
-
#
|
195
|
-
def add(start,duration)
|
196
|
-
# aim to calculate to the end of the day
|
197
|
-
start,duration = @values[start.wday].calc(start,duration)
|
198
|
-
return start,duration,false if (duration==0) || (start.jd > @finish.jd)
|
199
|
-
# aim to calculate to the end of the next week day that is the same as @finish
|
200
|
-
while((duration!=0) && (start.wday!=@finish.next_day.wday) && (start.jd <= @finish.jd))
|
201
|
-
if (duration>@values[start.wday].total)
|
202
|
-
duration = duration - @values[start.wday].total
|
203
|
-
start=start.next_day
|
204
|
-
elsif (duration==@values[start.wday].total)
|
205
|
-
start=after_last_work(start)
|
206
|
-
duration = 0
|
207
|
-
else
|
208
|
-
start,duration = @values[start.wday].calc(start,duration)
|
209
|
-
end
|
163
|
+
|
164
|
+
def add_full_weeks(a_date, a_duration)
|
165
|
+
|
166
|
+
while (a_duration != 0) && (a_duration >= self.week_total) && ((jd(a_date) + (6*86400)) <= jd(self.finish))
|
167
|
+
a_duration -= self.week_total
|
168
|
+
a_date += (7*86400)
|
210
169
|
end
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
|
217
|
-
|
170
|
+
|
171
|
+
[a_date, a_duration]
|
172
|
+
end
|
173
|
+
|
174
|
+
def add_remaining_days(a_date, a_duration)
|
175
|
+
while (a_duration != 0) && (jd(a_date) <= jd(self.finish))
|
176
|
+
a_date, a_duration = add_to_end_of_day(a_date,a_duration)
|
218
177
|
end
|
178
|
+
[a_date, a_duration]
|
179
|
+
end
|
219
180
|
|
220
|
-
|
181
|
+
def start_of_next_day(date)
|
182
|
+
next_day(date) - (HOUR * date.hour) - (MINUTE * date.min)
|
183
|
+
end
|
221
184
|
|
222
|
-
|
223
|
-
|
224
|
-
if (duration>@values[start.wday].total)
|
225
|
-
duration = duration - @values[start.wday].total
|
226
|
-
start=start.next_day
|
227
|
-
else
|
228
|
-
start,duration = @values[start.wday].calc(start,duration)
|
229
|
-
end
|
230
|
-
end
|
231
|
-
return start, duration, false
|
185
|
+
def subtract_to_start_of_day(a_date, a_duration, a_day)
|
186
|
+
|
232
187
|
|
188
|
+
a_date, a_duration, a_day = handle_midnight(a_date, a_duration, a_day)
|
189
|
+
|
190
|
+
r_date, r_duration, r_day = @days[a_date.wday].calc(a_date, a_duration)
|
191
|
+
|
192
|
+
[r_date, r_duration, r_day]
|
193
|
+
|
233
194
|
end
|
234
|
-
|
235
|
-
|
236
|
-
#
|
237
|
-
# @param [DateTime] start original date
|
238
|
-
# @param [Integer] duration minutes to subtract - always a negative
|
239
|
-
# @param [Boolean] midnight flag indicates the start date is midnight when true
|
240
|
-
# @return [DateTime, Integer, Boolean] the calculated date, remaining number of minutes and
|
241
|
-
# true if the time is midnight on the date
|
242
|
-
#
|
243
|
-
def subtract(start,duration,midnight=false)
|
195
|
+
|
196
|
+
def handle_midnight(a_date, a_duration, a_day)
|
244
197
|
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
198
|
+
if a_day == PREVIOUS_DAY
|
199
|
+
a_date -= DAY
|
200
|
+
a_date = Time.gm(a_date.year, a_date.month, a_date.day,LAST_TIME_IN_DAY.hour, LAST_TIME_IN_DAY.min)
|
201
|
+
|
202
|
+
if @days[a_date.wday].working?(a_date.hour, a_date.min)
|
203
|
+
a_duration += 1
|
204
|
+
end
|
249
205
|
end
|
250
206
|
|
251
|
-
|
252
|
-
|
207
|
+
[a_date, a_duration, SAME_DAY]
|
208
|
+
end
|
253
209
|
|
254
|
-
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
259
|
-
|
260
|
-
|
261
|
-
end
|
210
|
+
def subtract(a_date, a_duration, a_day)
|
211
|
+
a_date, a_duration, a_day = handle_midnight(a_date, a_duration, a_day)
|
212
|
+
a_date, a_duration, a_day = subtract_to_start_of_day(a_date, a_duration, a_day)
|
213
|
+
|
214
|
+
while (a_duration != 0) && (a_date.wday != start.wday) && (jd(a_date) > jd(start))
|
215
|
+
a_date, a_duration, a_day = handle_midnight(a_date, a_duration, a_day)
|
216
|
+
a_date, a_duration, a_day = subtract_to_start_of_day(a_date, a_duration, a_day)
|
217
|
+
end
|
262
218
|
|
263
|
-
|
264
|
-
|
219
|
+
while (a_duration != 0) && (a_duration >= week_total) && ((jd(a_date) - (6 * DAY)) >= jd(start))
|
220
|
+
a_duration += week_total
|
221
|
+
a_date -= 7
|
222
|
+
end
|
265
223
|
|
266
|
-
|
267
|
-
|
268
|
-
start=start.prev_day
|
269
|
-
else
|
270
|
-
start,duration=minute_b4_midnight(start,duration)
|
271
|
-
start,duration = @values[start.wday].calc(start,duration)
|
272
|
-
end
|
224
|
+
while (a_duration != 0) && (jd(a_date) > jd(start))
|
225
|
+
a_date, a_duration, a_day = subtract_to_start_of_day(a_date,a_duration,a_day)
|
273
226
|
end
|
274
227
|
|
275
|
-
|
228
|
+
[a_date, a_duration, a_day]
|
229
|
+
end
|
230
|
+
|
231
|
+
def diff_in_same_weekpattern(start_date, finish_date)
|
232
|
+
minutes = @days[start_date.wday].working_minutes(start_date, LAST_TIME_IN_DAY)
|
233
|
+
run_date = start_of_next_day(start_date)
|
234
|
+
while (run_date.wday != start.wday) && (jd(run_date) < jd(finish)) && (jd(run_date) != jd(finish_date))
|
235
|
+
minutes += @days[run_date.wday].working_minutes
|
236
|
+
run_date += DAY
|
237
|
+
end
|
276
238
|
|
277
|
-
|
278
|
-
|
279
|
-
|
280
|
-
start=start-7
|
239
|
+
while ((jd(run_date) + (7 * DAY)) < jd(finish_date)) && ((jd(run_date) + (7 * DAY)) < jd(finish))
|
240
|
+
minutes += week_total
|
241
|
+
run_date += (7 * DAY)
|
281
242
|
end
|
282
243
|
|
283
|
-
|
244
|
+
while (jd(run_date) < jd(finish_date)) && (jd(run_date) <= jd(finish))
|
245
|
+
minutes += @days[run_date.wday].working_minutes
|
246
|
+
run_date += DAY
|
247
|
+
end
|
284
248
|
|
285
|
-
|
286
|
-
|
287
|
-
if (
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
249
|
+
if run_date != finish_date
|
250
|
+
|
251
|
+
if (jd(run_date) == jd(finish_date)) && (jd(run_date) <= jd(finish))
|
252
|
+
minutes += @days[run_date.wday].working_minutes(run_date, finish_date - MINUTE)
|
253
|
+
run_date = finish_date
|
254
|
+
elsif (jd(run_date) <= jd(finish))
|
255
|
+
minutes += @days[run_date.wday].working_minutes
|
256
|
+
run_date += DAY
|
293
257
|
end
|
294
|
-
end
|
295
|
-
|
296
|
-
|
297
|
-
|
258
|
+
end
|
259
|
+
|
260
|
+
[minutes, run_date]
|
261
|
+
|
298
262
|
end
|
299
|
-
|
300
|
-
|
301
|
-
|
302
|
-
|
303
|
-
# @param [DateTime] start is the date whose midnight is to be used as the start date
|
304
|
-
# @param [Integer] duration is the number of minutes to subtract
|
305
|
-
# @return [DateTime, Integer] the date with a time of 23:59 and remaining duration
|
306
|
-
# adjusted according to whether 23:59 is resting or not
|
307
|
-
#
|
308
|
-
def minute_b4_midnight(start,duration)
|
309
|
-
start -= start.hour * HOUR
|
310
|
-
start -= start.min * MINUTE
|
311
|
-
duration += @values[start.wday].minutes(23,59,23,59)
|
312
|
-
start = start.next_day - MINUTE
|
313
|
-
return start,duration
|
314
|
-
end
|
315
|
-
|
316
|
-
# Calculates the date and time after the last working minute of the current date
|
317
|
-
#
|
318
|
-
# @param [DateTime] start is the current date
|
319
|
-
# @return [DateTime] the new date
|
320
|
-
#
|
321
|
-
def after_last_work(start)
|
322
|
-
if @values[start.wday].last_hour.nil?
|
323
|
-
return start.next_day
|
324
|
-
else
|
325
|
-
start = start + HOUR * (@values[start.wday].last_hour - start.hour)
|
326
|
-
start = start + MINUTE * (@values[start.wday].last_min - start.min + 1)
|
327
|
-
return start
|
328
|
-
end
|
263
|
+
|
264
|
+
def diff_in_same_day(start_date, finish_date)
|
265
|
+
minutes = @days[start_date.wday].working_minutes(start_date, finish_date - MINUTE)
|
266
|
+
[minutes, finish_date]
|
329
267
|
end
|
330
|
-
|
331
|
-
|
332
|
-
|
333
|
-
|
334
|
-
|
335
|
-
|
336
|
-
|
337
|
-
|
338
|
-
|
339
|
-
|
340
|
-
|
341
|
-
#rest of week to finish day
|
342
|
-
while (start.wday<finish.wday) do
|
343
|
-
duration+=@values[start.wday].total
|
344
|
-
start=start.next_day
|
345
|
-
end
|
346
|
-
#weeks
|
347
|
-
while (start.jd+7<finish_on.jd) do
|
348
|
-
duration+=@week_total
|
349
|
-
start+=7
|
350
|
-
end
|
351
|
-
#days
|
352
|
-
while (start.jd < finish_on.jd) do
|
353
|
-
duration+=@values[start.wday].total
|
354
|
-
start=start.next_day
|
355
|
-
end
|
356
|
-
#day
|
357
|
-
day_duration, start=@values[start.wday].diff(start,finish)
|
358
|
-
duration+=day_duration
|
359
|
-
return duration, start
|
268
|
+
|
269
|
+
def next_day(time)
|
270
|
+
time + DAY
|
271
|
+
end
|
272
|
+
|
273
|
+
def prev_day(time)
|
274
|
+
time - DAY
|
275
|
+
end
|
276
|
+
|
277
|
+
def jd(time)
|
278
|
+
Time.gm(time.year, time.month, time.day)
|
360
279
|
end
|
361
|
-
|
362
280
|
end
|
363
281
|
end
|