Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP Carbon date difference with only working days

Tags:

php

php-carbon

I'm trying to get difference between two dates in human format but only with working days. Here is my actual code:

$start = '2018-09-13 09:30:00';
$end = '2018-10-16 16:30:00';

$from = Carbon::parse($start);
$to = Carbon::parse($end);

$weekDay = $from->diffInWeekdays($to);
$human = $to->diffForHumans($from, true, false, 6);

var_dump($weekDay); //24
var_dump($human); // 1 month 3 days 7 hours

diffForHumans is perfect for my needs but I can't find any way of filtering like diffInDaysFiltered

What I would like to achieve is to get this result: 24 days 7 hours because we only have 24 working days

I tried a preg_replace first to replace 3 days by $weekDay result but if we have a month before it's incorrect and I have: 1 month 24 days 7 hours

Is there any solution for my problem ?

like image 214
Baptiste Avatar asked Jul 12 '18 14:07

Baptiste


People also ask

How can I get working days between two dates in PHP?

php //The function returns the no. of business days between two dates and it skips the holidays function getWorkingDays($startDate,$endDate,$holidays){ // do strtotime calculations just once $endDate = strtotime($endDate); $startDate = strtotime($startDate); //The total number of days between the two dates.

How do you calculate the difference between two dates in carbon?

You can only use the diffInDays() function on a Carbon instance. You can create a new one by parsing the end date you're receiving. $end = Carbon::parse($request->input('end_date'));

How do you subtract carbon days?

Alternate ways to find the solution to Carbon Date Minus Days is shown below. $day = '2019-10-30 18:29:19'; $date = Carbon::createFromFormat('Y-m-d H:i:s', $day); $date->subDay(); // Subtracts 1 day echo $date->format('Y-m-d h:i:s');

How do you find the difference between two dates in laravel carbon?

How to count days between two dates in Laravel? function dateDiffInDays($date1, $date2) { $diff = strtotime($date2) – strtotime($date1); return abs(round($diff / 86400)); } // Start date $date1 = "2021-03-01 04:03:00"; // End date $date2 = date('Y-m-d'); $dateDiff = dateDiffInDays($date1, $date2);


1 Answers

Here is the answer thanks to imbrish

I need to use the cascade factor to define:

  • How many hours is a day
  • How many days is a week
  • How many days is a month

Then with the diffFiltered I can only select weekday and working hours. You can also add a filter on public holiday thanks to macro

CarbonInterval::setCascadeFactors(array(
    'days' => array(10, 'hours'),
    'weeks' => array(5, 'days'),
    'months' => array(20, 'days'),
));

$resolution = CarbonInterval::hour();

$start = Carbon::parse('2017-07-13 11:00');
$end = Carbon::parse('2017-07-17 18:00');

$hours = $start->diffFiltered($resolution, function ($date) {
    return $date->isWeekday() && $date->hour >= 8 && $date->hour < 18;
}, $end);

$interval = CarbonInterval::hours($hours)->cascade();

echo $interval->forHumans(); // 2 days 7 hours

Here is the macro part:

Carbon::macro('isHoliday', function ($self = null) {
    // compatibility chunk
    if (!isset($self) && isset($this)) {
        $self = $this;
    }
    // Put your array of holidays here
    return in_array($self->format('d/m'), [
        '25/12', // Christmas
        '01/01', // New Year
    ]);
});

Then simply add && !$date->isHoliday() inside the diffFiltered

like image 166
Baptiste Avatar answered Sep 17 '22 18:09

Baptiste