1 | if not exports?
|
2 | if not @gi
|
3 | @gi = {}
|
4 | if not @gi.util
|
5 | @gi['util'] = {}
|
6 | if not @gi.util.common
|
7 | @gi.util['common'] = {}
|
8 |
|
9 | do (exports = (if exports? then exports else @gi.util.common['timePatterns'] = {} )) ->
|
10 | moment = if window? then window.moment else require('moment')
|
11 |
|
12 | enrichPeriod = (pattern, recurrence) ->
|
13 | length = 0
|
14 | secondsInADay = 60*60*24
|
15 |
|
16 | if recurrence is 'weekly'
|
17 | length = secondsInADay * 7
|
18 |
|
19 | #the create & update methods protect us from patterns
|
20 | #longer than the recurrence
|
21 | onTime = 0
|
22 | calculatedPeriodLength = 0
|
23 |
|
24 | for s, i in pattern
|
25 | if i % 2 == 1
|
26 | #an on period
|
27 | onTime += s
|
28 | calculatedPeriodLength += s
|
29 |
|
30 | if calculatedPeriodLength < length
|
31 | #push the difference on the end of the array
|
32 | missingSecondsInPattern = length - calculatedPeriodLength
|
33 | pattern.push missingSecondsInPattern
|
34 | #if it's an on period, add it to the periodOnTime
|
35 | if pattern.length % 2 is 0
|
36 | #the last entry is an on time
|
37 | onTime += missingSecondsInPattern
|
38 |
|
39 | length: length
|
40 | onTime: onTime
|
41 |
|
42 | calculatePeriodStart = (period, start, pattern, recurrence) ->
|
43 | period.start = moment(start)
|
44 | #now the difference is at most one recurrence length
|
45 | if recurrence is 'weekly'
|
46 | period.start = moment(start).startOf('week')
|
47 |
|
48 | period.secondsToStart = start.diff period.start, 'seconds'
|
49 |
|
50 | # console.log 'period start: ' + period.start.toString()
|
51 | # console.log 'start: ' + start.toString()
|
52 | # console.log 'seconds to start: ' + period.secondsToStart
|
53 | # console.log pattern
|
54 |
|
55 | period
|
56 |
|
57 | #
|
58 | # This is a complicated function, but it's well unit tested. I've left
|
59 | # the console lines in, but commented out to aid any future debugging
|
60 | # as they proved quite helpful to see what's going on
|
61 | #
|
62 | exports.timeOnBetween = (_start, _stop, pattern, recurrence) ->
|
63 | #clone the moments so we don't alter them for the calling function
|
64 | start = moment(_start)
|
65 | stop = moment(_stop)
|
66 | # console.log 'period start: ' + periodStart.toString()
|
67 | # console.log 'start: ' + start.toString()
|
68 |
|
69 | result = 0
|
70 |
|
71 | period = enrichPeriod pattern, recurrence
|
72 |
|
73 | #calculate the seconds we are into the period
|
74 | secondsFromStartToStop = stop.diff start, 'seconds'
|
75 |
|
76 | while secondsFromStartToStop > period.length
|
77 | #fast forward through whole periods if we can
|
78 | # console.log 'fast forwarding (added ' + period.onTime + ' seconds)'
|
79 | result += period.onTime
|
80 | start.add 'seconds', period.length
|
81 | secondsFromStartToStop = stop.diff start, 'seconds'
|
82 |
|
83 | # console.log 'seconds from start to stop ' + secondsFromStartToStop
|
84 |
|
85 | #now the difference is at most one recurrence length
|
86 | period = calculatePeriodStart period, start, pattern, recurrence
|
87 |
|
88 | index = 0
|
89 | while true
|
90 | #we want to fast forward to the right point in the index
|
91 | if period.secondsToStart >= pattern[index]
|
92 | # console.log 'subtracting ' + pattern[index]
|
93 | # + ' seconds from start'
|
94 | period.secondsToStart -= pattern[index]
|
95 | index += 1
|
96 | else
|
97 | # console.log 'found start index ' + index + ' plus ' +
|
98 | # period.secondsToStart + ' seconds '
|
99 | break
|
100 |
|
101 | #so now index points to the correct start point in the pattern
|
102 | #and secondsFromStart needs to be added to that index
|
103 | if index % 2 is 0
|
104 | #it's an off period
|
105 | # console.log 'considering off period ' + index
|
106 | if secondsFromStartToStop >= pattern[index] - period.secondsToStart
|
107 | # console.log 'increasing index'
|
108 | secondsFromStartToStop -= pattern[index] - period.secondsToStart
|
109 | index += 1
|
110 | else
|
111 | # console.log 'we are done'
|
112 | secondsFromStartToStop = 0
|
113 | else
|
114 | # console.log 'considering on period ' + index
|
115 | if secondsFromStartToStop >= pattern[index] - period.secondsToStart
|
116 | result += pattern[index] - period.secondsToStart
|
117 | secondsFromStartToStop -= pattern[index] - period.secondsToStart
|
118 | index += 1
|
119 | else
|
120 | result += secondsFromStartToStop
|
121 | secondsFromStartToStop = 0
|
122 |
|
123 | while secondsFromStartToStop > 0
|
124 | if index % 2 is 0
|
125 | #it's an off period
|
126 | # console.log 'considering off period ' + index
|
127 | if secondsFromStartToStop >= pattern[index]
|
128 | secondsFromStartToStop -= pattern[index]
|
129 | index += 1
|
130 | else
|
131 | secondsFromStartToStop = 0
|
132 | else
|
133 | #it's an on period
|
134 | # console.log 'considering on period ' + index
|
135 | if secondsFromStartToStop >= pattern[index]
|
136 | result += pattern[index]
|
137 | secondsFromStartToStop -= pattern[index]
|
138 | #console.log 'current result: ' + result
|
139 | index += 1
|
140 | else
|
141 | result += secondsFromStartToStop
|
142 | # console.log 'current result: ' + result
|
143 | secondsFromStartToStop = 0
|
144 |
|
145 | # console.log 'returning: ' + result
|
146 | # console.log ''
|
147 | result
|
148 |
|
149 |
|
150 | exports.timeAfterXSecondsOnFrom = (_start, x, pattern, recurrence) ->
|
151 | #clone the moments so we don't alter them for the calling function
|
152 | start = moment(_start)
|
153 | # console.log 'start: ' + start.toString()
|
154 |
|
155 | result = moment(start)
|
156 | #calculate the seconds into the period we are
|
157 | period = enrichPeriod pattern, recurrence
|
158 |
|
159 | while x > period.onTime
|
160 | #fast forward through whole periods if we can
|
161 | # console.log 'fast forwarding (' + period.onTime + ' seconds)'
|
162 | result.add('seconds', period.length)
|
163 | start.add('seconds', period.length)
|
164 | x -= period.onTime
|
165 |
|
166 | # console.log 'x remaining: ' + x
|
167 |
|
168 | period = calculatePeriodStart period, start, pattern, recurrence
|
169 |
|
170 | index = 0
|
171 | while true
|
172 | #we want to fast forward to the right point in the index
|
173 | if period.secondsToStart >= pattern[index]
|
174 | # console.log 'subtracting ' + pattern[index] +
|
175 | # ' seconds from start'
|
176 | period.secondsToStart -= pattern[index]
|
177 | index += 1
|
178 | if index is pattern.length
|
179 | index = 0
|
180 | #console.log 'index is incremented to: ' + index
|
181 | else
|
182 | # console.log 'found start index ' + index + ' plus ' +
|
183 | # period.secondsToStart + ' seconds'
|
184 | if index % 2 is 1
|
185 | x += period.secondsToStart
|
186 | result.subtract 'seconds', period.secondsToStart
|
187 | # console.log 'current result: ' + result.toString()
|
188 | break
|
189 |
|
190 | #so now index points to the correct start point in the pattern
|
191 | #and secondsFromStart needs to be added to that index
|
192 | # console.log x
|
193 | while x > 0
|
194 | if index % 2 is 0
|
195 | #it's an off period
|
196 | # console.log 'considering off period ' + index
|
197 | result.add 'seconds', pattern[index]
|
198 | index += 1
|
199 | if index is pattern.length
|
200 | index = 0
|
201 | else
|
202 | # console.log 'considering on period ' + index
|
203 | onSeconds = pattern[index]
|
204 | if x >= onSeconds
|
205 | result.add 'seconds', onSeconds
|
206 | x -= onSeconds
|
207 | index += 1
|
208 | if index is pattern.length
|
209 | index = 0
|
210 | else
|
211 | result.add 'seconds', x
|
212 | x = 0
|
213 |
|
214 | # console.log 'returning: ' + result
|
215 | # console.log ''
|
216 | result |
\ | No newline at end of file |