如何计算俩个时间的时间差?其中不含包含某个时间段

计算俩个时间差,其中不包含晚上十点之后到早上十点之前的时间段,用php该怎么实现呢?
比如第一个是昨天晚上九点,第二个时间是今天早上11点。则这俩个时间差是2俩个小时
有没有大佬有好的算法呢?(只需要考虑临近俩天的情况,可以都是当天,或者昨天和今天)

ps:我是有个订单需要超时自动取消。但是晚上10点到早上10点不算在内。因为这个时间段,用户没有时间处理订单,情有可原。但是在大白天超过5个小时没有操作就自动取消

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 51
$time1 = strtotime('2023-06-26 21:00:00');
$time2 = strtotime('2023-06-27 11:00:00');

var_dump('相差秒数:' . ($time2 - $time1 - 43200)); // string(19) "相差秒数:7200"
10个月前 评论
xiaofeishu (楼主) 10个月前
woodong (作者) 10个月前
xiaofeishu (楼主) 10个月前
woodong (作者) 10个月前
xiaofeishu (楼主) 10个月前
woodong (作者) 10个月前
xiaofeishu (楼主) 10个月前
use Carbon\Carbon;

function calculateTimeDifference($startDateTime, $endDateTime, $excludedStart, $excludedEnd)
{
    // 将时间字符串转换为 Carbon 对象
    $start = Carbon::parse($startDateTime);
    $end = Carbon::parse($endDateTime);
    $excludedStart = Carbon::parse($excludedStart);
    $excludedEnd = Carbon::parse($excludedEnd);

    // 检查起始时间是否在不包含的时间段内
    if ($start->between($excludedStart, $excludedEnd, false)) {
        $start = $excludedEnd;
    }

    // 检查结束时间是否在不包含的时间段内
    if ($end->between($excludedStart, $excludedEnd, false)) {
        $end = $excludedStart;
    }

    // 计算时间差
    $diff = $end->diff($start);

    return $diff;
}

// 输入起始时间和结束时间
$startDateTime = '2023-06-25 10:00:00';
$endDateTime = '2023-06-27 14:30:00';

// 输入不包含的时间段
$excludedStart = '2023-06-26 08:00:00';
$excludedEnd = '2023-06-26 20:00:00';

// 计算时间差
$timeDifference = calculateTimeDifference($startDateTime, $endDateTime, $excludedStart, $excludedEnd);

// 输出时间差
echo "时间差: " . $timeDifference->format('%d 天, %h 小时, %i 分钟');
10个月前 评论
xiaofeishu (楼主) 10个月前
徵羽宫 10个月前
xiaofeishu (楼主) 10个月前

直接一点:
分别将开始时间 / 结束时间 和 对应日期的 A/B 对比,比 A 小,取 A,比 B 大;
然后计算

  1. 开始时间到开始时间当天 B 的小时数(小于0 取 0) – 设为 a
  2. 结束时间当天 A 到结束时间的小时数(小于0 取 0) – 设为 b
  3. (间隔天数 - 1)* (B-A)的小时数 — 设为 c

将三者相加即可 a+b+c 注意: 如果 开始时间和结束时间在同一天,c 是负数

10个月前 评论
zhy (作者) 10个月前
xiaofeishu (楼主) 10个月前
zhy (作者) 10个月前
xiaofeishu (楼主) 10个月前
zhy (作者) 10个月前
function calculateTimeDifference($time1,$time2){
    $ts1_h = date("H",strtotime($time1));
    $ts2_h = date("H",strtotime($time2));
    if($ts1_h<10) $ts1_h=10;
    if($ts2_h<10) $ts2_h=10;
    if($ts1_h>22) $ts1_h=22;
    if($ts2_h>22) $ts2_h=22;
    if(date("Y-m-d",strtotime($time1)) == date("Y-m-d",strtotime($time2))){
        $gap_h =  $ts2_h-$ts1_h;
    }else{
        $gap_h =  12-$ts1_h+$ts2_h;

    }
    echo "相差{$gap_h}个小时";
}

$time1 = '2023-06-26 08:00:00';
$time2 = '2023-06-27 16:00:00';
calculateTimeDifference($time1,$time2);

优化了一下 ,不知道是否还有优化空间

10个月前 评论
zhy 10个月前
xiaofeishu (作者) (楼主) 10个月前
zhy 10个月前
zhy 10个月前
xiaofeishu (作者) (楼主) 10个月前
wxf666 10个月前
xiaofeishu (作者) (楼主) 10个月前

被排除晚上十点之后到早上十点之前的时间段有12小时

$baseDiffHours = 12;
$t1 = '2023-06-26 21:00:00';
$t2 = '2023-06-27 11:00:00';

$dateH1 = date('H', strtotime($t1));
$dateH2 = date('H', strtotime($t2));
$diffDays = Carbon::make($t1)->diffInDays($t2);
// diffInDays 方法需要判断两个时间的小时大小,以确定是否隔天
$diffDays = $dateH2 > $dateH1 ? $diffDays : $diffDays + 1;
// 既然不存在当天的时间,那么在计算两个日期的时间差时,减掉被排除的小时数*天数即可
$diffHours = Carbon::make($t1)->diffInHours($t2) - $diffDays * $baseDiffHours;
echo $diffHours;
10个月前 评论
xiaofeishu (楼主) 10个月前
xiaofeishu (楼主) 10个月前
    $begin = '2023-06-26 21:00:00';
    $end = '2023-06-27 11:00:00';

    $conut = 0;
    $next = 1;

    while (true){

        $time = date('Y-m-d H:i:s', $stamp = strtotime( "+{$next} hours", strtotime($begin)));
        $next ++;

        $hour = (int)date('H', $stamp);

        // 其中不包含 晚上十点之后 到 早上十点之前 的时间段
        if ($hour >= 22 || $hour < 10){
            continue;
        }

        $conut ++;

        if ($time == $end) break;
    }

    echo $conut;
10个月前 评论
xiaofeishu (楼主) 10个月前
seebyyu (作者) 10个月前
xiaofeishu (楼主) 10个月前
DogLoML

carbon的diff方法可以算两个时间的差值,有个参数,可以使其返回时间差的绝对值,或者带正负号。

10个月前 评论
xiaofeishu (楼主) 10个月前
DogLoML (作者) 10个月前
xiaofeishu (楼主) 10个月前
DogLoML

订单创建不付款,5小时自动取消,可以使用延迟任务

创建订单时,下单时间+5小时看有没有超过晚十点,如果没有就以这个时间为取消时间,如果超过,就减去晚十点,把剩余时间加到早上10点,作为取消订单的时间,设置延迟任务,如果执行时订单未支付,订单超时取消。

Laravel

10个月前 评论
GeorgeKing 9个月前
xiaofeishu (楼主) 10个月前

不包括晚上22点到早上10点,说明开始时间和结束时间是不在这个时间段的。

// 返回结果 floor() 一下取得整数小时差
function diff($datetime1, $datetime2)
{
    $diffHours = (strtotime($datetime1) - strtotime($datetime2))/3600;
    //  只管当天、前一天、后一天,时间差小于-36 小时、大于36小时不用管
    if ($diffHours < -12) {
        // 时间2是时间1的前一天
        return - $diffHours - 12;
    }
    if ($diffHours < 0) {
        // 同一天,时间2早于时间1
        return -$diffHours;
    }
    if ($diffHours < 12) {
        // 同一天,时间2晚于时间1
        return $diffHours;
    }
    if ($diffHours > 12) {
        // 时间2是时间1的后一天
        return $diffHours - 12;
    }
}
10个月前 评论
xiaofeishu (楼主) 10个月前
岭南伊爸 (作者) 10个月前
岭南伊爸 (作者) 10个月前
xiaofeishu (楼主) 9个月前
陈先生

可以使用 PHP 中的 DateTime 类来计算时间差,并在计算时排除晚上十点之后到早上十点之前的时间段。以下是示例代码:

// 设置时区
date_default_timezone_set('Asia/Shanghai');

// 创建两个时间对象
$start = new DateTime('yesterday 9:00 PM');
$end = new DateTime('today 11:00 AM');

// 排除晚上十点之后到早上十点之前的时间段
$start_hour = $start->format('G');
$end_hour = $end->format('G');

if ($start_hour >= 22) {
    $start->modify('+1 day');
}

if ($end_hour < 10) {
    $end->modify('-1 day');
}

// 计算时间差
$diff = $end->diff($start);

// 输出小时数
echo $diff->h + ($diff->days * 24);

在上面的代码中,首先设置了时区为亚洲/上海(Asia/Shanghai),然后创建了两个时间对象 $start 和 $end,分别表示昨天晚上 9 点和今天早上 11 点。接下来,通过获取 $start 和 $end 的小时数,判断是否需要排除晚上十点之后到早上十点之前的时间段。如果 $start 的小时数大于等于 22,说明此时间在晚上十点之后,需要将其调整为第二天凌晨零点;如果 $end 的小时数小于 10,说明此时间在早上十点之前,需要将其调整为昨天晚上十二点。最后,使用 DateTime 对象的 diff 方法计算时间差,并输出小时数。

需要注意的是,上述代码只能计算临近两天的情况,如果需要计算更长时间跨度的情况,可能需要进行额外的处理。

PS:答案来自 AI

10个月前 评论
xiaofeishu (楼主) 9个月前
pardon110
<?php

// 设置第一个时间点
$time1 = strtotime('2023-06-25 15:30:00'); // 更换为你的起始时间

// 设置第二个时间点
$time2 = strtotime('2023-06-26 09:45:00'); // 更换为你的结束时间

// 设置晚上10点和凌晨10点的时间点
$nightStartTime = strtotime('22:00:00');
$nightEndTime = strtotime('10:00:00 +1 day');

// 获取起始时间和结束时间在一天内的时间片段
$time1InDay = ($time1 - strtotime('today')) % 86400; // 一天有 86400 秒
$time2InDay = ($time2 - strtotime('today')) % 86400;

// 检查是否需要减去晚上10点到早上10点之间的时间
if (($time1InDay >= $nightStartTime && $time1InDay < $nightEndTime)
    || ($time2InDay >= $nightStartTime && $time2InDay < $nightEndTime)
) {
    $nightDiff = ($nightEndTime - $nightStartTime) / 3600; // 将秒转换为小时
} else {
    $nightDiff = 0;
}

// 计算时间差异,不包括晚上10点到早上10点之间的时间
$timeDiff = abs($time2 - $time1);
$hours = floor(($timeDiff / 3600) - $nightDiff);
$minutes = floor(($timeDiff % 3600) / 60);

// 输出时间差
echo "时间差:{$hours}小时 {$minutes}分钟";

?>
9个月前 评论
xiaofeishu (楼主) 9个月前

说个思路,就当一天只有十二个小时,输入时间不在正确时间区间内的,就修正到 早上10 点,然后计算就好了。

起止时间在同一天的就直接算差值:end_time - start_time

起止时间不在同一天的就:(end_date - start_date -1)*12 +(start_time 到 start 当天的结束时间的时间间隔)+(end 当天开始时间 到 end_time 的时间间隔)

9个月前 评论
/**  
 * @param string $startTime 开始时间  
 * @param string $endTime 结束时间  
 * @param int    $validStart 有效开始时间  
 * @param int    $validEnd 有效结束时间  
 * @param int    $interval 跨天间隔时间点  
 * @return mixed  
 */
function calculateTime(string $startTime, string $endTime, int $validStart = 9, int $validEnd = 20, int $interval = 0): mixed  
{  
    $startTime = is_numeric($startTime) ?: strtotime($startTime);  
    $endTime   = is_numeric($endTime) ?: strtotime($endTime);  
    // 开始时间 第一个时间点 时间戳  
    $startFirstValidTime = strtotime(date("Y-m-d $validStart:00:00", $startTime));  
    // 开始时间 第二个时间点 时间戳  
    $startSecondValidTime = strtotime(date("Y-m-d $validEnd:00:00", $startTime));  
    // 开始时间 第三个时间点 时间戳  
    $startThirdValidTime = strtotime(date("Y-m-d $interval:00:00", $startTime));  
    // 结束时间 第一个时间点 时间戳  
    $endFirstValidTime = strtotime(date("Y-m-d $validStart:00:00", $endTime));  
    // 结束时间 第二个时间点 时间戳  
    $endSecondValidTime = strtotime(date("Y-m-d $validEnd:00:00", $endTime));  
    // 结束时间 第三个时间点 时间戳  
    $endThirdValidTime = strtotime(date("Y-m-d $interval:00:00", $endTime));  
    $begin             = max($startTime, $startFirstValidTime);  
    $begin             = min($begin, $startSecondValidTime);  
    $now               = max($endTime, $endFirstValidTime);  
    $now               = min($now, $endSecondValidTime);  
    // 实际相差天数  
    $diffDays = intval(floor(($endThirdValidTime - $startThirdValidTime) / 86400));  
    return $now - $begin - (($validStart + 24 - $validEnd) * 3600 * $diffDays);  
}
echo calculateTime('2024-01-16 19:00:00', '2024-01-17 01:00:00');
3个月前 评论

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!