使用JavaScript比较时间范围

时间:2015-10-25 22:00:21

标签: javascript angularjs datetime momentjs angular-moment

我有一组Date对象形式的时间范围。我需要将这些时间范围与新的时间范围进行比较,以确保我不添加与现有时间范围重叠或重复的时间范围。

以下是该集合的一个示例。

var timeSlots = [
    {
        BeginTime: new Date("10/25/2015 8:00 AM"),
        EndTime: new Date("10/25/2015 8:45 AM")
    },
    {
        BeginTime: new Date("10/25/2015 9:00 AM"),
        EndTime: new Date("10/25/2015 9:45 AM")
    },
    {
        BeginTime: new Date("10/25/2015 9:50 AM"),
        EndTime: new Date("10/25/2015 10:30 AM")
    }
];

在前面的示例中,日期的日期部分无关紧要。时代呢。

如果我有一个新的时间范围对象,从上午9:30开始,我需要能够检测到它。

这是一个AngularJS应用程序,它可以访问MomentJS和Angular Moment。

如何获取新的时段对象并确保它不会与其他时段对象冲突?

// building off of the previous example
var newTimeSlot = newDate("10/25/2015 9:00 AM");
if (!conflictingTime(newTimeSlot)) {
    // then run my code
}

function conflictingTime(time) {
    // how do I do this?
}

3 个答案:

答案 0 :(得分:0)

由于这是一个开源项目,我希望这里有人喜欢SO点足以提出比我所做的更“优化的实践”或更优雅的解决方案。我想评论中的每个人都讨厌SO点。

所以这是我的解决方案。

angular.forEach($scope.timeSlots, function (timeSlot, index) {
    var beginTimeHasIssue = ($scope.timeSlot.BeginTime >= timeSlot.BeginTime && $scope.timeSlot.BeginTime <= timeSlot.EndTime);
    var endTimeHasIssue = ($scope.timeSlot.EndTime >= timeSlot.BeginTime && $scope.timeSlot.EndTime <= timeSlot.EndTime);

    if (beginTimeHasIssue || endTimeHasIssue) {
        hasError = true;
        $scope.HasTimeSlotError = true;
        return;
    } 
});

答案 1 :(得分:0)

你正在按照建议这样做的方式,但它看起来并不健全,例如:如果没有当前的插槽, forEach 将不会做太多。此外,它一直到最后,而不是一旦找到一个插槽就停止。请考虑以下事项:

var timeSlots = [
  {BeginTime: new Date("10/25/2015 8:00 AM"),
   EndTime: new Date("10/25/2015 8:45 AM")},
  {BeginTime: new Date("10/25/2015 9:00 AM"),
   EndTime: new Date("10/25/2015 9:45 AM")},
  {BeginTime: new Date("10/25/2015 9:50 AM"),
   EndTime: new Date("10/25/2015 10:30 AM")}
];

/*  @param   {Object} slot - object with BeginTime and EndTime date objects
 **  @returns {Boolean} true if slot fits, otherwise false
 */
function slotFits(slot) {
  if (timeSlots.length == 0) return true; // If no slots, must fit
  return timeSlots.some(function(s, i) {
    return (i == 0 && slot.EndTime <= s.BeginTime) || // slot is before all others
      (s.EndTime <= slot.BeginTime && !timeSlots[i + 1]) || // slot is after all others
      (s.EndTime <= slot.BeginTime && timeSlots[i + 1].BeginTime >= slot.EndTime) // Slot between others
  });
}

[{BeginTime: new Date("10/25/2015 7:00 AM"),  // before all, true
  EndTime: new Date("10/25/2015 8:00 AM")},
 {BeginTime: new Date("10/25/2015 10:30 AM"),  // after all, true
  EndTime: new Date("10/25/2015 11:00 AM")},
 {BeginTime: new Date("10/25/2015 8:45 AM"),  // between 0 and 1, true
  EndTime: new Date("10/25/2015 9:00 AM")},
 {BeginTime: new Date("10/25/2015 8:45 AM"),  // Overlap 1, false
  EndTime: new Date("10/25/2015 9:15 AM")}
].forEach(function(slot, i) {
  console.log('Slot ' + i + ': ' + slotFits(slot));
});

这也可以优化,一旦它通过所有机会找到一个插槽就停止,需要两行代码。您应该能够根据角度代码进行调整。

PS。我通常不会使用字符串(即使用非标准字符串的内置解析器)以这种方式创建日期,但这对于此示例就足够了。真的应该使用以下内容创建日期:

var date = moment('10/25/2015 9:15 AM', 'MM/DD/YYYY h:mm Z').toDate();

console.log(date.toString());
<script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.22.2/moment.min.js"></script>

答案 2 :(得分:0)

   addTimeSlot=function(newtimeSlot){
        var beginTimeHasIssue = false;
        var endTimeHasIssue = false;
        timeSlots.forEach(function (timeSlot, index) {
            if( newtimeSlot.BeginTime >= timeSlot.BeginTime &&  newtimeSlot.EndTime <= timeSlot.EndTime ) {
                 console.log('falls inbetween');
                endTimeHasIssue = true;
            } 
            if( newtimeSlot.BeginTime <= timeSlot.BeginTime &&  newtimeSlot.EndTime >= timeSlot.EndTime) {
                 console.log('falls inbetween');
                beginTimeHasIssue = true;
            }      
        });
        if (beginTimeHasIssue || endTimeHasIssue) {
            console.log('error');
            return;
        } else {
            timeSlots.push(newtimeSlot)
            console.log('saved');
        }
        if (timeSlots.length == 0) {
          timeSlots.push(newtimeSlot);
        }
    }