PHP 业务 跨日/不跨日/24小时 营业时间段判断

需求分析

当我们有一个需求,内容是给一个健身房门店设置营业时间

要求限制客户只能在该门店营业时间范围内进行预约健身操作

在这里插入图片描述


面临情况

24小时营业

营业时间 == 结业时间

在这里插入图片描述

营业时间不跨日

营业时间 < 结业时间

在这里插入图片描述

营业时间跨日

营业时间 > 结业时间

在这里插入图片描述


分析业务并实现

(xx:xx 这种不带日期的时间称为“时刻”或“时间点)

我们目前知道的是,客户会挑选指定时间段(例 :2023-03-24 9:00 ~ 2023-03-24 10:30)来进行健身门店的预约操作

那么在我们现在所面临的三种情况中,可以知道 24小时营业 与 营业时间不跨日这两种情况可以说是最简单解决的,

唯一麻烦的是营业时间跨日的问题

解决代码如下:

/**
 * 判断当前时间是否在门店营业时间内
 * 
 * @param array $store_time 门店营业范围[开业时间,结业时间]
 * @param array $datetime 客户预约门店时间范围[开始时间,结束时间]
 * @return bool 
 */
function isStoreBusinessHours(array $store_time, array $datetime): bool
{
  //先拿到开业结业的时间点,把他们转成当日的时间点时间戳,进行对比
  $open_time_TIM = strtotime($store_time[0]); //开业时间点时间戳
  $close_time_TIM = strtotime($store_time[1]); //结业时间点时间戳

  //24小时营业
  if ($open_time_TIM == $close_time_TIM) {
    return true;
  }

  $start_datetime = strtotime($datetime[0]); //客户起始时间(时间戳)
  $end_datetime = strtotime($datetime[1]); //客户结束时间(时间戳)

  //营业时间无跨日
  if ($open_time_TIM < $close_time_TIM) {
    //此时不能继续使用$open_time_TIM与$close_time_TIM进行范围比较
    //因为$open_time_TIM与$close_time_TIM是用来直接转换为今日的时间点进行判断门店营业类型的
    //如果客户预约的时间不是今日,是明天或者后天,就不能继续使用
    //这时候我们需要将门店营业的时间点与客户的预约时间的日期(不带时间点)来合并成一个完整的日期时间

    //例:营业时间点 08:00 - 12:00 客户预约的日期时间 2023-03-24 8:30 ~  2023-03-24 09:00
    //第一步:从客户的起始日期时间中提取 2023-03-24 的日期,并转换为时间戳
    //第二步:将客户的起始日期时间的时间戳与门店营业时间点(无日期的时间)合并在一起成为门店开业/结业日期时间时间戳

    $date_TIM = strtotime(date('Y-m-d', $start_datetime)); //客户起始时间的日期时间戳提取
    //门店开业/结业日期时间时间戳 = 客户起始预约时间时间戳 +  开业/结业无日期时间的时间戳
    //(为什么只用起始预约时间戳?因为门店营业时间为不跨日,客户若跨日了就直接不允许预约了)
    $open_datetime = getDatetimeTimestamp($date_TIM, $store_time[0]);
    $close_datetime = getDatetimeTimestamp($date_TIM, $store_time[1]);
    if ($start_datetime >= $open_datetime && $end_datetime <= $close_datetime) {
      return true;
    }
  }

  //跨日营业
  if ($open_time_TIM > $close_time_TIM) {
    //先获取到当前时间的年月日,按照不同跨日结业时间,再将门店开业/结业的无日期的时间合并回来,再进行时间戳对比
    //解释: 
    //假如门店营业营业时间为跨日营业 08:00 ~ 02:00 
    //情况一:客户预约时间为 2023-03-25 08:30 ~ 2023-03-26 02:00 属于在当日的跨日营业时间范围
    //情况二:客户预约时间为 2023-03-25 00:00 ~ 2023-03-25 02:00 属于在昨日的跨日营业时间范围
    //今跨日结业时间
    $date_TIM = strtotime(date('Y-m-d', $start_datetime));
    $cross_date_TIM = strtotime('+1 day', strtotime(date('Y-m-d', $start_datetime)));
    $open_datetime = getDatetimeTimestamp($date_TIM, $store_time[0]); //今跨日营业的起始时间
    $close_datetime = getDatetimeTimestamp($cross_date_TIM, $store_time[1]); //今跨日营业的结束时间
    if ($start_datetime >= $open_datetime && $end_datetime <= $close_datetime) {
      return true;
    }

    //昨跨日结业时间
    $date_TIM = strtotime('-1 day', strtotime(date('Y-m-d', $start_datetime)));
    $cross_date_TIM = strtotime(date('Y-m-d', $start_datetime));
    $open_datetime = getDatetimeTimestamp($date_TIM, $store_time[0]); //昨跨日营业的起始时间
    $close_datetime = getDatetimeTimestamp($cross_date_TIM, $store_time[1]); //昨跨日营业的结束时间
    if ($start_datetime >= $open_datetime && $end_datetime <= $close_datetime) {
      return true;
    }
  }

  return false;
}

/**
 * 将日期和时间拼接成时间戳
 * 
 * @param int $startDatetime 起始时间戳
 * @param string $time 时间点字符串
 * @return int 时间戳
 */
function getDatetimeTimestamp(int $startDatetime, string $time)
{
  return strtotime(date('Y-m-d', $startDatetime) . " {$time}");
}
  • 3
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值