A Pen by not important on CodePen.
Created
December 9, 2016 07:18
-
-
Save clindsey/71136bd46c83cdcad1139ee2cf998a39 to your computer and use it in GitHub Desktop.
schedule-logic-1.0.0
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const scheduleLogic = { | |
calculateTimeRange: (settings, targetDate, startTime, endTime) => { | |
const initialTime = scheduleLogic.calculateFirstTime(settings, targetDate); | |
const startTimes = scheduleLogic.calculateStartTimes(settings, initialTime); | |
let newStartTime = targetDate.clone().hours(startTime.hours()).minutes(startTime.minutes()); | |
let findResult = startTimes.find(time => time.toISOString() === newStartTime.toISOString()); | |
if (!findResult) { | |
newStartTime = startTimes[0]; | |
} | |
const endTimes = scheduleLogic.calculateEndTimes(settings, initialTime, newStartTime); | |
let newEndTime = targetDate.clone().hours(endTime.hours()).minutes(endTime.minutes()); | |
if (newEndTime.hours() < moment(settings.endTime, 'HHmm').hours()) { | |
newEndTime.add(1, 'day'); | |
} | |
findResult = endTimes.find(time => time.toISOString() === newEndTime.toISOString()); | |
if (!findResult) { | |
newEndTime = endTimes[0] | |
} | |
return { | |
endTime: newEndTime, | |
endTimes, | |
startTime: newStartTime, | |
startTimes | |
}; | |
}, | |
calculateFirstTime: (settings, targetDate) => { | |
const { | |
endTime, | |
minLeadTime, | |
timeIncrement | |
} = settings; | |
const startTime = moment(settings.startTime, 'HHmm'); | |
const now = moment(); | |
let hours = startTime.hours(); | |
let minutes = startTime.minutes(); | |
const firstTime = targetDate.clone().set({hours, minutes}); | |
if (firstTime.isBefore(now)) { // this handles the today case | |
now.add(minLeadTime, 'minutes'); | |
const minutes = now.minutes(); | |
const minuteDelta = (Math.ceil(minutes / timeIncrement) * timeIncrement) - minutes; | |
const todayFirstTime = now.add(minuteDelta, 'minutes').seconds(0).milliseconds(0); | |
// refactor, handle cases after 9:30, it generates too many options and they're out of valid range | |
return todayFirstTime; | |
} | |
return firstTime; | |
}, | |
calculateStartTimes: (settings, initialTime) => { | |
const { | |
endTime, | |
maxDuration, | |
minDuration, | |
timeIncrement | |
} = settings; | |
const latestTime = moment(endTime, 'HHmm').subtract(minDuration, 'minutes'); | |
if ((maxDuration / timeIncrement) % 2) { // hopefully this prevents an infinite loops in thie `while` below | |
throw new Error('Invalid settings: `maxDuration` must be evenly divisable by `timeIncrement`'); | |
} | |
const startTimes = [ | |
initialTime.clone() | |
]; | |
while (true) { // eslint-disable-line no-constant-condition | |
const time = startTimes[startTimes.length - 1].clone(); | |
startTimes.push(time.add(timeIncrement, 'minutes')); | |
if (time.format('HHmm') === latestTime.format('HHmm')) { | |
break; | |
} | |
} | |
return startTimes; | |
}, | |
calculateEndTimes: (settings, initialTime, startTime) => { | |
const { | |
endTime, | |
minDuration, | |
maxDuration, | |
timeIncrement | |
} = settings; | |
const earliestTime = startTime.clone().add(minDuration, 'minutes'); | |
let remainingTime = maxDuration; | |
const endTimes = [ | |
earliestTime.clone() | |
]; | |
while (remainingTime) { | |
remainingTime -= timeIncrement; | |
const time = endTimes[endTimes.length - 1].clone(); | |
if (time.format('HHmm') === endTime) { | |
break; | |
} | |
endTimes.push(time.add(timeIncrement, 'minutes')); | |
} | |
return endTimes; | |
}, | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment