【问题标题】:Check if time ranges overlap and trigger error if true检查时间范围是否重叠,如果为真则触发错误
【发布时间】:2014-07-09 19:57:21
【问题描述】:

抱歉这个问题太长了,但是您需要了解一些背景才能完全理解:

我正在 Drupal 7 中构建一个事件调度程序,它允许用户选中一个复选框以将事件添加到他们的日程安排中......这很混乱。复选框包含一个类似于1404915600 - 1404917400 的值,它代表10:30am - 10:50am,这是使用PHP 的结果strtotime(); 函数,如strtotime("10:30am");

如果用户选中另一个具有重叠时间的框作为先前选择的事件,我需要即时检查,如果存在重叠则触发错误。

目前,我正在使用上面提到的 php 函数在复选框中创建值,然后在单击复选框时将这些值传递给 javascript 数组。复选框的id 是所选事件的url 友好名称,它充当数组键,值是所选时间,因此数组最终看起来像:

timeArr = { event-name-one: 0: 1404915600, 1: 1404917400 }

每个事件都有自己的键来简化使用 Javascripts delete 函数删除(或取消调度)事件。

这里是获取复选框 ID 和相关时间并将它们存储在数组中的完整代码:

var timeBox = jQuery('input[type="checkbox"].time, input[type="checkbox"].time2');
var timeArr = [];

// Listen for checkbox change
timeBox.bind('click', function() {

    var eventID = jQuery(this).attr('id');

    // If Checkbox IS checked
    if(jQuery(this).prop('checked')) {

        var timeStamp = jQuery(this).val();
        var newTime = timeStamp.split(" - ");

        // If timeArr has been set
        if(timeArr.length > 1) {

            for(key in timeArr) {
                if(newTime[0] > timeArr[key][0] && newTime[0] < timeArr[key][1] || timeArr[key][0] > newTime[0] && timeArr[key][0] < newTime[1]) {
                    alert("Overlap!");
                    return false;
                } else {
                    timeArr[eventID].push(newTime);
                    console.log(timeArr);
                }
            }           

        } else {
            // else timeArr hasn't been set -- so set it!                
            timeArr[eventID] = newTime;
            console.log(timeArr);
        }
    } else {
        delete timeArr[eventID];
    }        
});

我似乎无法让新选择的事件时间与数组中的当前时间进行交叉检查。它们只是被附加到 timeArr 数组中,就好像检查通过了一样。

我这样做是完全错误的方式还是我只是错过了一些东西?我尝试了很多不同的事情,我很迷茫,不知道哪个是正确的方向。如果有帮助,我正在使用 Drupal 7。

【问题讨论】:

  • 请记住,任何来自表单字段的内容都将是一个字符串,来自.split() 的任何内容也是如此。 '9' &gt; '44' 在 JS 中为 TRUE,而9 &gt; 44 为 FALSE。
  • 所以我需要使用parseInt(); 来返回一个整数吗?编辑:实际上,我需要遍历数组并在每个值上使用 parseInt(); 吗?
  • 是的。由于您正在执行仅在数字上下文中有意义的操作,因此您必须将这些字符串转换为数字。当然,您的大多数时间戳都将非常接近,因此现在不太可能成为问题。但在某些时候你会被这个咬伤,并且不知道为什么'9' &lt; '8'会失败。
  • 是的,你需要 parseInt 来获得一个整数值。为了检测 JS 中的重叠,您最好创建一个 JS Date 对象并与之进行比较。公式为start1 &lt; end2 &amp;&amp; end1 &gt; start2。这将检测所需的所有 4 个比较中的重叠。您还需要确定确切的开始和结束时间是包含还是不包含。 IE。如果某件事以 1000 结束,而其他事情从 1000 开始,它们是否会在 1000 分钟内重叠?
  • @JonathanKuhn 您能否提供一个示例,说明如何使用 JS Date 对象转换这些时间?编辑:如果一个以 1000 结束,而其他东西以 1000 开始,则不被视为重叠。

标签: javascript php jquery arrays checkbox


【解决方案1】:

公式为start1 &lt; end2 &amp;&amp; end1 &gt; start2。这将检测所需的所有 4 个比较中的重叠(如下)。您还需要确定确切的开始和结束时间是包含还是不包含。 IE。如果某事以 1000 结束,而其他事从 1000 开始,它们是否会在 1000 分钟内重叠?

重叠的四个条件是:

  1. Event1 与 Event2 的开始重叠(Event1:10am-12am,Event2:11am-1pm)
  2. Event1 与 Event2 的结尾重叠(Event1:10am-12am,Event2:9am-11am)
  3. Event1 完全包含 Event2(Event1:10am-12am,Event2:1030am-1130am)
  4. Event2 完全包含 Event1(Event1:10am-12am,Event2:9am-1pm)

上面的公式涵盖了所有 4 种可能的情况。

【讨论】:

    猜你喜欢
    • 2016-06-30
    • 1970-01-01
    • 2017-06-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-02-28
    • 1970-01-01
    相关资源
    最近更新 更多