phpphp-carbon

Date range comparison unexpected output despite inclusion of target date


I'm encountering an unexpected outcome when attempting to compare dates in my PHP code. Here's what I'm doing:

<?php
$date = Carbon::now()->locale('fr_FR');
$date->subMonth();
$previousMonth = ucfirst($date->monthName) . ' ' . $date->year;
$currentDate = Carbon::now()->locale('fr_FR');
$currentDate->firstOfMonth();
$firstDayOfPreviousMonth = $currentDate->subMonth()->firstOfMonth(); // "2024-02-01"
$lastDayOfPreviousMonth = $firstDayOfPreviousMonth->copy()->lastOfMonth(); // "2024-02-29"

$carbonSubmissionTime = Carbon::createFromTimestamp(1709216823); // "2024-02-29"
if ($carbonSubmissionTime->gte($firstDayOfPreviousMonth) && $carbonSubmissionTime->lte($lastDayOfPreviousMonth)) {
    echo "ok";
}else{
    echo "nok";
}

You can test the code in: https://play.phpsandbox.io/embed/nesbot/carbon

The expectation is to receive "ok" because "2024-02-29" falls within the range of "2024-02-01" and "2024-02-29". However, the actual result is "nok".

What might be causing this discrepancy?

EDIT

I also tried using betweenIncluded but gives the same result:

if($carbonSubmissionTime->betweenIncluded($firstDayOfPreviousMonth, $lastDayOfPreviousMonth)){}

Solution

  • The discrepancy comes from the fact that $carbonSubmissionTime also has a time component to it where $lastDayOfPreviousMonth has its time set to 00:00:00.

    If we add the following debug statements before the comparison, the issue is apparent:

    echo "The submission time is ", $carbonSubmissionTime->toDateTimeString(), "\n";
    echo "First day of previous month is ", $firstDayOfPreviousMonth->toDateTimeString(), "\n";
    echo "Last day of previous month is ", $lastDayOfPreviousMonth->toDateTimeString(), "\n";
    

    This yields:

    The submission time is 2024-02-29 14:27:03

    First day of previous month is 2024-02-01 00:00:00

    Last day of previous month is 2024-02-29 00:00:00

    Either change the last day of the previous month to have a time of 23:59:59, or zero out the time like so:

    $carbonSubmissionTime = $carbonSubmissionTime->startOfDay(); // "2024-02-29 00:00:00"
    

    Making either of those changes produces the desired output.

    A basic date string comparison also works:

    if (
        $carbonSubmissionTime->toDateString() >= $firstDayOfPreviousMonth->toDateString()
        && $carbonSubmissionTime->toDateString() <= $lastDayOfPreviousMonth->toDateString()
    ) {