-2

我想以分钟为单位计算两个日期之间的时间,同时只包括 和 之间的时间08:00:0016:30:00也不包括周六和周日。我怎样才能做到这一点?以下是我的代码,它通常只是计算两个日期之间的时间。

foreach($result as $row)
{
    $sub_array = array();
    $sub_array[] = floor((strtotime($row['app_2_date'])-strtotime($row['app_1_date']))/(60));
    $data[] = $sub_array;
}

我已经尝试了以下代码,但仍然无法正常工作

foreach($result as $row)
{
    if
        (
            date('H:i:s', strtotime($row['app_2_date'])) > date('H:i:s', strtotime('1970-01-01 16:30:00'))||
            date('H:i:s', strtotime($row['app_2_date'])) < date('H:i:s', strtotime('1970-01-01 08:00:00'))
        )
    {
        $sub_array[] = floor((strtotime($row['app_3_date'])-strtotime($row['app_2_date']))/(60))-(15.5*60);
    }
    else
    {
        $sub_array[] = floor((strtotime($row['app_3_date'])-strtotime($row['app_2_date']))/(60));
    }
}
4

2 回答 2

1
WITH RECURSIVE
cte AS ( SELECT TIMESTAMP(DATE(MIN(dtfrom)), '08:00:00') dtfrom, 
                TIMESTAMP(DATE(MIN(dtfrom)), '16:30:00') dttill
         FROM src 
         UNION ALL
         SELECT dtfrom + INTERVAL 1 DAY,
                dttill + INTERVAL 1 DAY
         FROM cte
         WHERE dtfrom <= ( SELECT MAX(dttill)
                           FROM src ) )
SELECT src.id, SUM(TIMESTAMPDIFF(MINUTE, GREATEST(src.dtfrom, cte.dtfrom), LEAST(src.dttill, cte.dttill))) minutes
FROM src
CROSS JOIN cte
WHERE GREATEST(src.dtfrom, cte.dtfrom) < LEAST(src.dttill, cte.dttill)
  AND WEEKDAY(cte.dtfrom) < 5
GROUP BY src.id

小提琴

于 2020-09-16T07:26:01.427 回答
0

这是一种面向对象的方法。我在 PHP 版本 7.4.9 上。

我假设您拥有Composer为 PHP 项目带来的强大功能。

我使用Carbon库创建了这个示例,以极大地扩展默认的 DateTime API。

use Carbon\Carbon;
use Carbon\CarbonPeriod;
use Carbon\CarbonInterval;

$start = Carbon::now();
$end = $start->copy()->addMonth();

$days = new CarbonPeriod($start, $end);
$workDays = [];

foreach ($days as $day) {
    if (! $day->isWeekend()) {
        $dayStart = $day->isSameDay($start) ?
            $start : $day->copy()->setTime(8, 00);
    
        $dayEnd = $day->isSameDay($end) ?
            $end : $day->copy()->setTime(16, 30);

        $workDays[] = new CarbonPeriod(
            $dayStart,
            $dayEnd,
            CarbonInterval::minute()
        );
    }
}
$minutes = 0;

foreach ($workDays as $workDay) {
   $minutes += iterator_count($workDay);
}
var_dump($minutes) // int(11242)

请注意,我没有仔细检查结果。

测试用例

为了快速测试此方法,您可以使用PsySH 之类的交互式 PHP shell

在这种情况下,我会假设:

  • 您在一个类似 UNIX 的系统上。
  • PHP 已安装并在您的 CLI 中可用。
  • GIT 已安装并在您的 CLI 中可用。
  • Composer 未安装/不可用。
git clone git@github.com:briannesbitt/Carbon.git carbon
cd carbon
php -r "copy('https://getcomposer.org/download/1.10.13/composer.phar', 'composer');"
chmod u+x composer
./composer install
./composer require psy/psysh
./vendor/bin/psysh

PsySH 正在运行并且您已进入。现在将 PHP 代码示例复制到剪贴板并粘贴到 PsySH shell 中。

于 2020-09-16T11:40:29.570 回答