简体   繁体   English

从繁忙时间范围中获取可用时间范围

[英]Get available time ranges from an array of busy time ranges

Lets say you have an array of BUSY time ranges for a meeting 假设您有一系列繁忙的会议时间范围

[{'start':'9:00 AM', 'end':'10:00 AM'},
{'start':'12:00 PM', 'end':'2:00 PM'},
{'start':'5:00 AM', 'end':'7:00 PM'}]

I would like to get in return an array of AVAILABLE times in a 24 hour frame, that are the opposite of the above times. 我想在24小时内返回一组可用时间,与上述时间相反。 Like... 喜欢...

[{'start':'00:00 AM', 'end':'9:00 AM'},
 {'start':'10:00 AM', 'end':'12:00 PM'},
 {'start':'2:00 PM', 'end':'5:00 PM'},
 {'start':'7:00 PM', 'end':'11:59 PM'}]

I have tried using moment.js as well as https://www.npmjs.com/package/moment-range , specifically the .subtract() method. 我尝试过使用moment.js以及https://www.npmjs.com/package/moment-range ,尤其是.subtract()方法。

I am aware of similar stackoverflow questions but couldn't find ones that were applicable to this format, in javascript, with momentJS, and elegant ES6 array method solution. 我知道类似的stackoverflow问题,但找不到包含适用于此格式的问题,这些问题在javascript中,带有momentJS和优雅的ES6数组方法解决方案。

 function giveUtc(start) { var t = moment().format("YYYY-MM-DD") var t1 = t + " " + start return moment(t1, "YYYY-MM-DD h:mm A").format() } const timeRange = [{ 'start': '9:00 AM', 'end': '10:00 AM' }, { 'start': '12:00 PM', 'end': '2:00 PM' }, { 'start': '5:00 PM', 'end': '7:00 PM' }, { "start": "11:00 AM", "end": "3:00 PM", }, { "start": "6:00 PM", "end": "9:00 PM", }] timeRange.sort((a, b) => { var utcA = giveUtc(a.start) var utcB = giveUtc(b.start) if (utcA < utcB) { return -1 } if (utcA > utcB) { return 1 } return 0 }) const availableTimeArray = [] let endTimeFarthest = moment(giveUtc("0.00 AM")) let startTimeMinimum = moment(giveUtc("12.59 PM")) timeRange.forEach((element, index) => { let currentEndTime = moment(giveUtc(element.end)) const currentStartTime = moment(giveUtc(element.start)) if (currentStartTime.isBefore(startTimeMinimum)) { startTimeMinimum = currentStartTime } if (currentEndTime.isAfter(endTimeFarthest)) { endTimeFarthest = currentEndTime } /* console.log(startTimeMinimum.format("h:mm A"), endTimeFarthest.format("h:mm A")) */ if (index === timeRange.length - 1) { if (timeRange.length === 1) { availableTimeArray.push({ start: "00:00 AM", end: currentStartTime.format("h:mm A") }) } availableTimeArray.push({ //start: currentEndTime.format("h:mm A"), start: endTimeFarthest.format("h:mm A"), end: "11.59 PM" }) } else { const nextBusyTime = timeRange[index + 1] const nextStartTime = moment(giveUtc(nextBusyTime.start)) if (index === 0) { availableTimeArray.push({ start: "00:00 AM", end: currentStartTime.format("h:mm A") }) } let endTimeToCompare = currentEndTime.isBefore(endTimeFarthest) ? endTimeFarthest : currentEndTime if (endTimeToCompare.isBefore(nextStartTime)) { availableTimeArray.push({ start: endTimeToCompare.format("h:mm A"), end: nextStartTime.format("h:mm A") }) } } }) console.log(availableTimeArray) 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.5.1/moment.min.js"></script> 

I have used utc timestamp to compare between timings and assumed that all the interval belongs to a single day. 我使用utc时间戳比较时间,并假设所有间隔都属于一天。 Some edge case might be missing but you can take the idea. 一些边缘情况可能会丢失,但是您可以采用这个想法。 I have made use of greedy algorithm. 我已经利用贪婪算法。 First sorting all the interval based on the start time. 首先根据开始时间对所有间隔进行排序。 Then iterating through the sorted array to pick correct interval 然后遍历排序后的数组以选择正确的间隔

I have been overthinking this. 我一直在想这个。 Simple loops should be enough 简单的循环就足够了

I have not tested this 100% so there may be edge cases. 我没有对此进行100%的测试,因此可能会出现边缘情况。

 const busy = [{'start':'9:00 AM', 'end':'10:00 AM'}, {'start':'12:00 PM', 'end':'2:00 PM'}, {'start':'5:00 PM', 'end':'7:00 PM'}]; const last = busy.length-1; let avail = []; function norm(t) { let [,hh,mm,ampm] = /(\\d{1,2}):(\\d{2}) ([AP]M)/.exec(t); return {"hh": ampm=="PM"? +hh+12:hh,"mm":mm } } function makeUSTime(hh) { return (hh>12?hh-12:hh)+":00"; } for (let i=0,j=0;i<busy.length;i++) { for (;j<=24;j++) { if (norm(busy[i].start).hh>j) { avail.push({"start":makeUSTime(j),"end":busy[i].start}); j=norm(busy[i].end).hh; break; } } } if (norm(busy[last].end).hh<24) avail.push({"start":busy[last].end,"end":"11:59 PM"}); console.log(avail) 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM