Search code examples
phplaravelphp-carbon

CarbonPeriod is not returning incomplete days


I want to split into days:

2021-03-23T00:00:00Z
2021-03-24T23:00:00Z

Which represent 1 day and 1 hour.

If I try to make a carbon period with those:

$periods = CarbonPeriod::create($start, "1 day", $end);

It will return:

[0] = 2021-03-23T00:00:00Z
[1] = 2021-03-24T00:00:00Z

And I will lose 1 hour.

How should I do to make it return:

[0] = 2021-03-23T00:00:00Z
[1] = 2021-03-24T00:00:00Z
[2] = 2021-03-24T00:23:00Z

Or if it is not possible, at least:

[0] = 2021-03-23T00:00:00Z
[1] = 2021-03-24T00:00:00Z
[2] = 2021-03-25T00:00:00Z

Solution

  • I believe that's how it's intended to work. If you want to include that last date that doesn't amount to a full period, you'll have to add it on your own.

    Including '2021-03-24T23:00:00Z' at the end.

    $start = '2021-03-23T00:00:00Z';
    $end = '2021-03-24T23:00:00Z';
    
    $period = (new Carbon($start))->toPeriod($end); // default period is +1d
    
    $periodArray = $period->toArray();
    if (!last($periodArray)->is($end)) {
        $periodArray[] = new Carbon($end);
    }
    

    Last lines can be converted into a single statement with tap()

    $periodArray = tap($period->toArray(), function(&$array) use ($end) {
        if (!last($array)->is($end)) {
            $array[] = new Carbon($end);
        }
    });
    

    Including '2021-03-25T00:00:00Z' at the end

    $start = '2021-03-23T00:00:00Z';
    $end = '2021-03-24T23:00:00Z';
    
    $period = (new Carbon($start))->toPeriod(
        (new Carbon($end))->startOfDay()->is($end)
            ? $end
            : (new Carbon($end))->addDays(1)
    );
    
    $periodArray = $period->toArray();