workpattern 0.3.4 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|