laravel 如何找出一个时间段有多少是在工作时间之内,有多少是在这个时间之外?

pzfprimi  于 2023-04-13  发布在  其他
关注(0)|答案(2)|浏览(171)

为了计算工作时间,我需要分别计算用户在工作时间内(09:00 - 17:00)和工作时间外(加班)的工作时间,并返回它们的总和。
例如,用户工作时间为2023-01-23 15:002023-01-23 22:00,其中2023-01-23 15:002023-01-23 17:00为工作时间,2023-01-23 17:002023-01-23 22:00为加班时间。
现在,我如何才能知道用户的工作时间有多少是在9:0017:00范围内,有多少是在时间之外?

foreach ($timeSheets as $key => $time) {
    if ($time->is_in == 1) {
        $time_in = new Carbon($time->event_at);
        $time_out = new Carbon($timeSheets[$key + 1]->event_at);
        [$time_in, $time_out] = $this->getTimeZoneName($bill->BillingRateTimezone->timezone, $time_in, $time_out);
        // period of his/her work time
        $start_time = $time_in->format("H:i");
        $end_time = $time_out->format("H:i");

        // How can I calculate how much of user work time is between 9:00-17:00 and how much is outside of this  ??
                        
        $sumOfInside = "?";
        $sumOfOutside = "?";
    }
}
2lpgd968

2lpgd9681#

可能有更好的方法来绕过它,但是一堆条件语句来覆盖每种情况也是可行的。
案例一:

[-------------]                                         user hours  
                         [------------------]                    9:00 to 17:00  
  |    |    |    |    |    |    |    |    |    |    |    |    |  
  0    2    4    6    8    10   12   14   16   18   20   22   24

案例二:

[-----------]      user hours  
                         [------------------]                    9:00 to 17:00  
  |    |    |    |    |    |    |    |    |    |    |    |    |  
  0    2    4    6    8    10   12   14   16   18   20   22   24

案例三:

[-------------]                       user hours  
                         [------------------]                    9:00 to 17:00  
  |    |    |    |    |    |    |    |    |    |    |    |    |  
  0    2    4    6    8    10   12   14   16   18   20   22   24

案例四:

[-------------]                               user hours  
                         [------------------]                    9:00 to 17:00  
  |    |    |    |    |    |    |    |    |    |    |    |    |  
  0    2    4    6    8    10   12   14   16   18   20   22   24

案例五:

[-------------]                 user hours  
                         [------------------]                    9:00 to 17:00  
  |    |    |    |    |    |    |    |    |    |    |    |    |  
  0    2    4    6    8    10   12   14   16   18   20   22   24

案例六:

[--------------------------]                 user hours  
                         [------------------]                    9:00 to 17:00  
  |    |    |    |    |    |    |    |    |    |    |    |    |  
  0    2    4    6    8    10   12   14   16   18   20   22   24

使用Carbon的diff方法对此非常有用,但是由于需要日期时间,Carbon::today()(或者如果您想使用laravel助手,则只需today())可以给予我们提供时间为00:00:00的日期,这非常适合我们的需求。至于获得总和,我们可以递增地添加到CarbonInterval的几个示例中。

$inside_working_time = CarbonInterval::make('0h 0m 0s');
$outside_working_time = CarbonInterval::make('0h 0m 0s');

// start and end of work day
$_9 = Carbon::today()->add('9h');
$_17 = Carbon::today()->add('17h');
foreach (...) {
    ...
    $user_start = Carbon::today()->add($time_in->format('H\h i\m'));
    $user_end = Carbon::today()->add($time_out->format('H\h i\m'));

    $inside_working_interval = CarbonInterval::make('0h 0m 0s');
    $outside_working_interval = CarbonInterval::make('0h 0m 0s');

    // Case 1
    if ($user_start->lessThan($_9) && $user_end->lessThanOrEqualTo($_9)) {
        $outside_working_interval->add($user_start->diff($user_end));
    }
    // Case 2
    elseif ($user_start->greaterThanOrEqualTo($_17) && $user_end->greaterThan($_17)) {
        $outside_working_interval->add($user_start->diff($user_end));
    }
    // Case 3
    elseif ($user_start->greaterThanOrEqualTo($_9) && $user_end->lessThanOrEqualTo($_17)) {
        $inside_working_interval->add($user_start->diff($user_end));
    }
    // Case 4
    elseif ($user_start->lessThan($_9) && $user_end->between($_9, $_17)) {
        $inside_working_interval->add($_9->diff($user_end));
        $outside_working_interval->add($user_start->diff($_9));
    }
    // Case 5
    elseif ($user_start->between($_9, $_17) && $user_end->greaterThan($_17)) {
        $inside_working_interval->add($user_start->diff($_17));
        $outside_working_interval->add($_17->diff($user_end));
    }
    // Case 6
    elseif ($user_start->lessThan($_9) && $user_end->greaterThan($_17)) {
        $inside_working_interval->add($_9->diff($_17));
        $outside_working_interval->add($user_start->diff($_9);
        $outside_working_interval->add($_17->diff($user_end));
    }

    $inside_working_time->add($inside_working_interval);
    $outside_working_time->add($outside_working_interval);
}

然后,您可以使用forHumans()方法打印出时间间隔,或者获得总小时数和分钟数。

$inside_working_time->forHumans() // (string) 'X hours and Y minutes'

$inside_working_time->cascade()->h // (int) hours
$inside_working_time->cascade()->i // (int) the minutes that remain

$inside_working_time->totalHours // (float) hours expressed as decimal (for example 7.333 hours for 7h 20m
f4t66c6m

f4t66c6m2#

可以使用https://github.com/kylekatarnls/business-time
例如,使用diffInBusinessMinutes方法,您可以获得分钟数,而使用CarbondiffInMinutes方法,您可以获得总数,因此分钟数是从总数中减去的第一个。

相关问题