【问题标题】:Laravel: Skip time slots from Carbon\CarbonPeriod some time rangesLaravel:跳过 Carbon\CarbonPeriod 一些时间范围的时间段
【发布时间】:2021-07-18 09:37:56
【问题描述】:

我正在为各种套餐开发一个预订系统,每个套餐都有不同的持续时间。客户应该从选定的日期获得可用的时间段。该日期可能包含具有不同时间间隔的不同包裹预订。所以,我要做的是通过跳过所有预订的时间段来提取日期的可用时间段。

预期输出是:

08:00 AM
10:30 AM // 09:00 AM has a booking. and its duration is 1.5 hours
11:30 AM // The current package has 1 hour duration

... until the shop closes for eg 08:00 PM

我正在使用 CarbonPeriod 来获取时间段列表。但是,我无法应用过滤器来跳过所有预订的时间段。

$hours = new CarbonPeriod(
    $opening,
    $this->duration() . ' minutes',
    $closing->subMinutes($this->duration())
);

$hours->filter(function ($date) use ($booked) {
    $toSkip = [];
    foreach ($booked as $bookedItem) {
        $bookingTime = Carbon::parse($bookedItem->time);
        $completingTime = Carbon::parse($bookedItem->time)->addMinutes($bookedItem->package->duration());

        if ($date->isBetween($bookingTime, $completingTime)) {
            array_push($toSkip, $date);
        }
    }
    return !in_array($date, $toSkip);
});

任何帮助将不胜感激!

【问题讨论】:

  • 我想您的问题之一是您的 return 语句在您的 foreach 循环内。这意味着它的过滤方法只会检查$booked中的第一项
  • @Rwd,感谢您的支持!这是我将 return 语句放在循环之外后得到的结果:[ "11:00 AM", "02:00 PM", "03:00 PM", "04:00 PM", "05:00 PM", "06:00 PM", "07:00 PM", ] 但是,在上午 10:30 - 上午 11:00、下午 01:30 - 下午 2:30 之间缺少一个时段。我能做到这一点吗?谢谢

标签: php laravel php-carbon


【解决方案1】:

如果您不想重新发明轮子,这听起来像是 spatie/opening-hours 的工作或专用于 Carbon 的版本:cmixin/business-time

定义如下:

BusinessTime::enable(Carbon::class, [
  'monday' => ['09:00-12:00', '13:00-18:00'],
  'tuesday' => ['09:00-12:00', '13:00-18:00'],
  'wednesday' => ['09:00-12:00'],
  'thursday' => ['09:00-12:00', '13:00-18:00'],
  'friday' => ['09:00-12:00', '13:00-20:00'],
  'saturday' => ['09:00-12:00', '13:00-16:00'],
]);

然后用CarbonPeriod,使用自定义步骤:

$period = CarbonPeriod::create(
    $opening,
    static fn ($date) => $date->nextOpen(),
    $closing,
);

foreach ($period as $slot) {
  echo "$slot\n";
}

您还可以轻松地将 AM/PM 字符串转换为 h0-23 格式:

Carbon::parse('11:20 PM')->format('H:i')

【讨论】:

  • 感谢您的回复。但是,这不符合我的要求。我必须向客户显示可用时间段的列表。这个包对于检查所选时间是否可用非常有帮助。
  • 一旦你有了范围,你应该使用 ->nextOpen() 循环遍历,当然你不应该每分钟都迭代,它会非常慢。
猜你喜欢
  • 2020-01-18
  • 1970-01-01
  • 2019-10-17
  • 1970-01-01
  • 1970-01-01
  • 2017-02-10
  • 2021-05-10
  • 2020-09-17
  • 2022-01-03
相关资源
最近更新 更多