Laravel避免重叠日期

时间:2018-05-21 05:16:49

标签: laravel laravel-5

我是Laravel的新手,我正在尝试实施任何一天都无法重叠的预订日期。

我有一个名为'预订'包括room_id,start_date和end_date。

我有验证检查结束日期不能在开始之前:

$this->validate($request, [
        'start_date' => 'required|date',
        'end_date' => 'required|date|after_or_equal:start_date',
]);

但是我不确定如何检查日期范围是否与预订表中存储的同一room_id的任何其他日期范围冲突(因为一个房间不能在同一范围内预订两次)。

任何帮助将不胜感激,

谢谢!

4 个答案:

答案 0 :(得分:1)

在典型的重叠情况下,给定两个事件A和B,您必须考虑以下四种情况:

  1. 事件A包含事件B
  2. 事件B包含事件A
  3. 事件A的结束日期与事件B的开始日期重叠
  4. 事件B的结束日期与事件A的开始日期重叠

因此,在sql中检查某个日期间隔内房间是否忙碌,可以说是2018-11-20'和'2018-11-30':

select * 
from rooms 
where 
    start_date between '2018-11-20' and '2018-11-30' or 
    end_date between '2018-11-20' and '2018-11-30' or 
    '2018-11-20' between start_date and end_date or 
    '2018-11-30' between start_date and end_date;

在laravel中,我要做的是在模型中创建范围。

public function scopeByBusy($query,$start_date,$end_date) 
{ 
    return $query->whereBetween('start_date', [$start_date, $end_date]) 
        ->orWhereBetween('end_date', [$start_date, $end_date]) 
        ->orWhereRaw('? BETWEEN start_date and end_date', [$start_date]) 
        ->orWhereRaw('? BETWEEN start_date and end_date', [$end_date]); 
}

最后,我可以验证ID为95的房间在'2018-11-20'和'2018-11-30'之间是否正忙,如下所示:

$room_id = 95;
$start = '2018-11-20';
$end = '2018-11-30';
$exists = Rooms::where('id', $room_id)
    ->byBusy($start, $end)
    ->first();

if($exists)
{
    echo "the room is busy in the interval you selected";
}

希望对您有帮助。

答案 1 :(得分:0)

内置Carbon方法isPast(),因此您可以使用:

$start_date->isPast()
$end_date->isPast()

您可以查看过去是否已选择所选内容。

如果您还没有使用过碳,那就是链接: https://carbon.nesbot.com/docs/

答案 2 :(得分:0)

我有一个类似的用法,我需要检查人们是否已经在日期范围内安排了一些事情

下面的laravel示例代码:

 $start = Carbon::parse($request['start_date'])->format('Y-m-d 00:00:00');
 $end = Carbon::parse($request['end_date'])->format('Y-m-d 23:59:59');
 $existsActive = Microsite::where(function ($query) use ($start) {
                                      $query->where('start_date', '<=', $start);
                                      $query->where('end_date', '>=', $start);
                                  })->orWhere(function ($query) use ($end) {
                                      $query->where('start_date', '<=', $end);
                                      $query->where('end_date', '>=', $end);
                                  })->count();
 if(existsActive > 0 ){
    echo "Already exists";  
 }

答案 3 :(得分:-1)

你必须在数据库中检查。所以你可以这样做:

    val inputSet:Set[String] = inputColumns.map
    {
      cht => cht.stringLabel.toLowerCase()
    }.distinct.toSet
     logger.debug("\n\ninputSet\n"+inputSet.mkString(", "))

    val extantSet:Set[String] = extantColumns.map
    {
      e => e._1.toLowerCase()
    }.toSet

    logger.debug("\n\nextantSet\n"+inputSet.mkString(" * "))
    inputSet.diff(extantSet)