如何检查 laravel eloquent 中的 2 个日期和时间范围是否重叠

How to check if 2 dates and time ranges overlaps in laravel eloquent

我正在为一个智能储物柜项目构建一个预订系统。

用户应该能够在他需要的时间通过网站预订储物柜,显然,我需要确保没有超额预订。

我正在尝试使用 eloquent 构建查询以获取用户请求日期的预订总数。

到目前为止,我在我的控制器中完成了以下操作:

public function create(Request $request)
    {

        $locationId = $request->input('location_id');
        $beginningDate = Carbon::parse($request->input('beginning_date'))->format('d-m-Y');
        $beginningTime = Carbon::parse($request->input('beginning_time'))->format('H:m');
        $duration = $request->input('duration');

        $totalPrice=PriceList::where('duration_to_hours', $duration)->value('price');

        $reservationStartingDate = $beginningDate. ','.$beginningTime;

        $calculateReservationDates = Carbon::parse($reservationStartingDate)->addHours($duration);

        $endDate= $calculateReservationDates->format('d-m-Y');
        $endTime = $calculateReservationDates->format('H:m');

       $reservedCount = Reservation::where('beginning_date',  '<=', $endDate)
        ->where('end_date', '>=', $beginningDate)
        ->where('beginning_time', '<=', $endTime)
        ->where('end_time', '>=', $beginningTime)
        ->count();

        $totalBoxes = Box::where('location_id', $locationId)->count();

        dd($totalBoxes, $reservedCount);

        $available = false;

        if($totalBoxes > $reservedCount){
            $available = true;
        }


        return view('checkout', compact('locationId', 'totalPrice', 'endDate', 'endTime', 'beginningDate', 'beginningTime', 'duration', 'available'));
    }

如果用户请求的日期和时间与其他预订相同,则此查询有效。

假设从 06/04/2022 晚上 7 点开始预订了 2 小时,总共只有一个盒子可用。 如果新用户尝试在相同的时间和日期进行预订,那么 return 没有空房,但是,如果用户尝试从 2022 年 6 月 4 日晚上 7 点 30 分开始预订 2 小时return是说有空位,但实际上应该return没有空位。

我不知道我遗漏了什么,你知道我该如何解决这个问题吗?

谢谢

您需要检查条件:

来自用户的时间请求:

 A : beginning_time, B : end_time

这与 DB 中的记录有 4 个案例匹配:

 Y : beginning_time_record, Z : end_time_record 

案例 1:

Y -> A -> Z -> B

案例 2:

Y -> A -> B -> Z

案例 3:

A -> Y -> Z -> B

案例 4:

A -> Y -> B -> Z

同于:

$existReservation = Reservation::orWhere(function ($q1) use ($beginningDatetime, $endDatetime) {
   $q1->where('beginning_date_time', '>=', $beginningDatetime )
      ->where('beginning_date_time', '<=', $endDatetime);
})
->orWhere(function ($q2) use ($beginningDatetime, $endDatetime) {
   $q2->where('end_date_time', '>=', $beginningDatetime )
      ->where('end_date_time', '<=', $endDatetime);
})
->orWhere(function ($q3) use ($beginningDatetime, $endDatetime) {
   $q3->where('beginning_date_time', '>=', $beginningDatetime)
      ->where('end_date_time', '<=', $endDatetime);
})
->orWhere(function ($q4) use ($beginningDatetime, $endDatetime) {
   $q4->where('beginning_date_time', '<=', $beginningDatetime)
      ->where('end_date_time', '>=', $endDatetime);
})
->count();

或组条件:

$existReservation = Reservation::orWhere(function ($q1) use ($beginningDatetime, $endDatetime) {
       $q1->where('beginning_date_time', '>=', $beginningDatetime )
          ->where('beginning_date_time', '<=', $endDatetime);
    })
    ->orWhere(function ($q2) use ($beginningDatetime, $endDatetime) {
       $q2->where('beginning_date_time', '<=', $beginningDatetime )
          ->where('end_date_time', '>=', $beginningDatetime );
    })
    ->count();

检查无可用性

数据库:beginning_date_timeend_date_time