'Carbon less than equals returns false even though the date and times are the same
I am working on a website and I am writing some tests for it - testing if some records were created with the correct data and if the records are created after the start of the test by comparing the created_at date with the one I generate at the start of the test. Initially, I was using lt (less than method) rather than lte (less than or equals method on carbon) which I thought was causing the problem but then I switched to lte and the problem persisted. I've used xdebug to debug the problem but, strangely, in my IDE it shows the datetime strings to be exactly the same yet it returns false. Note that the majority of the cases it returns true and it works but every now and then it doesn't. Also, note this a Laravel app running PHP 8.0.
Here is the code where the magic happens, look around line 55 (note it has some debugging code to make it more understandable):
<?php
namespace App\Helpers\Tests;
use App\Models\Devices\Device;
use App\Actions\Common;
use Illuminate\Support\Carbon;
use Exception;
class DatabaseRecords {
/**
* Tests if records in the db match the one in $data,
* as well as if records in db have been created
* after the start of the test.
*/
public static function testRecords($test, $data, $deviceId, $type = 'mqtt')
{
$device = Device::findOrFail($deviceId);
foreach ($data as $sensorType => $items) {
$sensors = $device->sensors()->where('type', $sensorType)->where('channel', $items['channel'])->get();
if ($sensors->count() > 1) {
throw new Exception('More than one sensor of the same type and channel.');
}
$sensor = $sensors->first();
$lastRecords = $sensor->getLastFewDataRecords();
if (Common::isMultiValueSensor($sensor->type)) {
foreach ($items['data'] as $item) {
foreach ($lastRecords as $record) {
if ($item->stype === $record['stype']) {
$test->assertEquals($item->value, $record['value']);
$test->assertTrue($test->startTime->lte(new Carbon($record['created_at'])));
}
}
}
} else {
if ($type === 'mqtt') {
$value = $items['data'][0]->value;
} else {
$value = $items['data'];
}
$test->assertEquals($value, $lastRecords[0]['value']);
$startTimeString = $test->startTime->toDateTimeString();
$recordCreatedTimeString = $lastRecords[0]['created_at'];
$recordCreatedCarbon = Carbon::parse($recordCreatedTimeString);
if (! $test->startTime->lte($recordCreatedCarbon)) {
$test2 = $recordCreatedCarbon->toDateTimeString();
echo 'test';
}
$test->assertTrue($test->startTime->lte(Carbon::parse($recordCreatedTimeString)));
}
}
}
}
here is a screenshot of my IDE while debugging it:
I've tried googling for Carbon bugs but found nothing.
Solution 1:[1]
Turns out the problem was in the milliseconds as @apokryfos suggested. Just make sure the Carbon instances don't have milliseconds if you are not using them. One way to do that is by initializing Carbon this way:
Carbon::parse(date('Y-m-d H:i:s'));
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | Petar Vasilev |

