如何检查事件日期是否与现有事件重叠

时间:2014-03-13 12:43:59

标签: php sql yii criteria date-range

如何检查日期范围是否重叠?我在我的模型中有这个,它一直在保存。

public function dateRangeExists($attribute, $params) {
    $criteria = new CDbCriteria;

    $criteria->compare('id_one',$this->id_one,true,);
    $criteria->compare('id_two',$this->id_two,true,'OR');
    // $criteria->addCondition('start_date < '.$this->start_date);
    // $criteria->addCondition('end_date > '.$this->end_date);

    $criteria->addBetweenCondition('start_date', $this->start_date, $this->end_date);
    $criteria->addBetweenCondition('end_date', $this->start_date,$this->end_date);

    $record = self::model()->exists($criteria); 

    if(!empty($record)) {
         $this->addError('id', 'Item already exists within range.');
         return false;
    }
}

1 个答案:

答案 0 :(得分:1)

事件重叠有三种可能的情况:

  1. 在当前事件之前开始的事件(结束日期在当前事件开始日期之后)
    enter image description here

  2. 当前事件发生时开始的事件(开始日期早于当前事件结束日期)
    enter image description here

  3. 事件在当前事件期间开始和结束(可以忽略,因为上述任一规则仍适用)
    enter image description here

  4. 如上所述,您需要做的事情是检查现有事件是否存在,其中结束日期在当前开始日期之后(#1),或者开始日期在当前结束日期之前(#2)。请注意使用关键字OR

    WHERE (start_date < $this->start_date AND end_date > $this->start_date)
    OR (start_date < $this->end_date AND end_date > $this->end_date)
    

    要将此应用于Yii上下文,我会这样做:

    $criteria = new CDbCriteria;
    $criteria->addCondition(
        "WHERE (end_date > '{$this->start_date}' OR start_date < '{$this->end_date}')".
        "OR (start_date < '{$this->end_date}' AND end_date > '{$this->end_date}')"
    );
    

    我还会在客户端使用可视日历来阻止已经有事件的日期,以避免用户选择这些日期。

    如果您使用的是jQueryUI,这是一个现有的解决方案:jquery UI datepicker - disabling date ranges