如何检查日期范围是否重叠?我在我的模型中有这个,它一直在保存。
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;
}
}
答案 0 :(得分:1)
事件重叠有三种可能的情况:
在当前事件之前开始的事件(结束日期在当前事件开始日期之后)
当前事件发生时开始的事件(开始日期早于当前事件结束日期)
事件在当前事件期间开始和结束(可以忽略,因为上述任一规则仍适用)
如上所述,您需要做的事情是检查现有事件是否存在,其中结束日期在当前开始日期之后(#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