【问题标题】:Get available time ranges from an array of busy time ranges从繁忙时间范围数组中获取可用时间范围
【发布时间】:2018-01-23 17:37:01
【问题描述】:

假设您有一组 BUSY 会议时间范围

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

我想在 24 小时内返回一组 AVAILABLE 时间,这与上述时间相反。喜欢...

[{'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'}]

我尝试过使用 moment.js 以及 https://www.npmjs.com/package/moment-range,特别是 .subtract() 方法。

我知道类似的 stackoverflow 问题,但找不到适用于这种格式、javascript、momentJS 和优雅的 ES6 数组方法解决方案的问题。

【问题讨论】:

  • 要从社区获得帮助,请在您的问题中添加Minimal, Complete, and Verifiable example
  • 我现在尝试首先获取给定日期所有 15 分钟增量的数组。声明数组var array = []。声明一天的开始var m = moment().startOf('day').unix();。环形! for ( i = 0; i <= 96 ; i++){ m+=900; array.push(m); } 然后,一旦我有了这个数组,我想我 array.splice(start, deleteCount) 并且更改后的数组将有效 available
  • 我希望你有一个错字:{'start':'5:00 AM', 'end':'7:00 PM'} 否则会有重叠
  • 我确信我一直在想这件事。我不敢相信我们需要 moment.js 来进行简单的整数数学。我会再试一次

标签: javascript ecmascript-6 momentjs


【解决方案1】:

我一直在想这个。 简单的循环就足够了

我还没有 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)

【讨论】:

  • 感谢您的回复!我不确定谁反对你的尝试,但我很感激!
  • 是的,我也想知道。至少他们可以告诉我为什么他们不喜欢这个建议。它似乎按预期工作 - 可能需要更多工作,但我将其留给实施者
【解决方案2】:

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)
&lt;script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.5.1/moment.min.js"&gt;&lt;/script&gt;

我使用 utc 时间戳来比较时间,并假设所有时间间隔都属于一天。一些边缘案例可能会丢失,但你可以接受这个想法。我使用了贪心算法。首先根据开始时间对所有区间进行排序。然后遍历排序数组以选择正确的间隔

【讨论】:

  • 这太不可思议了。我看到您首先处理了边缘时间,然后在范围之间工作......最重要的是,您使用辅助函数将其保存在 UTC 中。谢谢,这就是为什么 stackoverflow 是这样的
  • @stack26 效果不好。添加另一个 timeRange 'start': '11:00 AM', 'end': '3:00 PM' 并查看结果
  • 是的,你是对的,错过了这个边缘案例,正在编辑我的答案。现在检查,请告诉我
  • 还有一些边缘情况。将最后一个“结束”时间从晚上 9:00 更改为下午 6:30。感谢您的努力@stack26
  • @daniherculano:让我检查一下。感谢提及
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-02-09
  • 2022-01-03
  • 2023-01-10
相关资源
最近更新 更多