Hello.
When using the microsecond precision, comparion ignores this part;
Example & workaround solution here:
use Carbon\Carbon;
$arr = [
Carbon::parse('2015/03/31 12:59:10.012203'),
Carbon::parse('2015/03/31 12:59:10.034936'),
Carbon::parse('2015/03/31 12:59:10.012393'),
];
usort($arr, function ($a, $b) {
if ($a->eq($b)) {
return $a->micro < $b->micro ? -1 : 1;
}
return $a->lt($b) ? -1 : 1;
});
var_dump($arr);
I get them in order...
array(3) {
[0]=>
object(Carbon\Carbon)#2 (3) {
["date"]=>
string(26) "2015-03-31 12:59:10.012203"
["timezone_type"]=>
int(3)
["timezone"]=>
string(15) "America/Toronto"
}
[1]=>
object(Carbon\Carbon)#4 (3) {
["date"]=>
string(26) "2015-03-31 12:59:10.012393"
["timezone_type"]=>
int(3)
["timezone"]=>
string(15) "America/Toronto"
}
[2]=>
object(Carbon\Carbon)#3 (3) {
["date"]=>
string(26) "2015-03-31 12:59:10.034936"
["timezone_type"]=>
int(3)
["timezone"]=>
string(15) "America/Toronto"
}
}
If you switch your comparison I get them back in desc order.
Using what code? The snippet i posted solves the bug i am trying to report by checking the microsecond when eq() returns true even though microsecond differs, so it's supposed to return them like you posted.
All three of those timestamps has eq === TRUE in my env. I figured it was to do with __toString() using the default formatting, which does not have a .u (microsecond) and thus comparison thinks they are equal.
Ah gotcha. Actually the implementation just uses the underlying comparison operators (==, <, >) and DateTime doesn't do anything with microseconds.
Any update on this? I am hitting the same bug.
personally, i ditched the php code i had that was depending on this and rewrote it in golang; https://github.com/martinlindhe/subtitles/blob/master/srt_test.go#L11
PR in progress to handle microtime comparisons : #614
No BC by the way
We just rely on the PHP comparison and that's how it works before PHP 7.1, microseconds are ignored but starting with PHP 7.1, sorting like this should work natively.