使用JavaScript比较时间范围 [英] Use JavaScript to compare time ranges

查看:92
本文介绍了使用JavaScript比较时间范围的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a collection of time ranges in the form of Date objects. I need to compare those time ranges against a new time range to make sure I don't add a time range that overlaps or duplicates an existing time range.

这是该系列的一个例子.

Here's an example of the collection.

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")
    }
];

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

In the previous example, the date part of the dates don't matter. The times do.

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

If I have an new time range object that begins at 9:30 AM, I need to be able to detect that.

这是在AngularJS应用程序内部,并且可以访问MomentJS和Angular Moment.

This is inside of an AngularJS app and it has access to both MomentJS and Angular Moment.

如何获取一个新的时隙对象,并确保它不会与现有的其他时隙对象冲突?

How can I take a new time slot object and ensure that it won't conflict with the others that exist?

// 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?
}

推荐答案

您的操作方式如建议的那样,但是似乎并不健壮,例如如果没有当前插槽,则 forEach 不会做太多事情.而且,它一直一直到结束,而不是在找到插槽后就停止.请考虑以下内容:

The way you're doing it is as suggested, however it doesn't seem robust, e.g. if there are no current slots the forEach won't do much. Also, it goes all the way to the end rather than stopping once it's found a slot. Consider the following:

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));
});

也可以将其优化为一旦找到插槽就停止了,这需要另外两行代码.您应该能够使其适应您的角度代码.

This could also be optimised to stop once it's passed all chance of finding a slot, requires two more lines of code. You should be able to adapt this to your angular code.

PS.我通常不会以这种方式使用字符串(即使用内置的非标准字符串解析器)来创建Date,但是对于此示例而言已足够.确实应该使用以下方式创建日期:

PS. I would not usually create Dates this way using a string (i.e. using the built-in parser for non-standard strings), but it's sufficient for this example. The Dates really should be created using something like:

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>

这篇关于使用JavaScript比较时间范围的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆