When creating an Carbon instance with today(), the milliseconds seem to be set to the current value instead to "000000".
This bug appears with Carbon >=1.24.0 and PHP 7.0.25.
Looking through the code I find this commit to be the culprit: https://github.com/briannesbitt/Carbon/commit/f863708fa1b5c777e80e8dafa0441683dff260ff
The problem lies with the way the date is being built in Carbon's constructor.
While attaching the microseconds to the time string in DateTime's constructor will allow the injection of microseconds into the DateTime object, also in PHP 7, there is no way to manipulate this value after initialization as setTime() only gained the microsecond-parameter in PHP 7.1, and setting the time without that parameter will not touch the microsecond value, unlike in PHP 7.1.
Indeed, it's a PHP <= 7.0 limitation. It happened because we added microseconds to now() and now() is used in today(), with Carbon 2, we'll drop PHP 7.0 and will simply be able to do ->setTime(0, 0, 0, 0) but before PHP 7.1 DateTime::setTime take only 3 arguments.
So a work-around could be to use Carbon::parse('today')
I will check if we should use it in our today() method.
Yes, but I cannot upgrade to PHP 7.1 for the moment and Carbon's version 1.24.0 introduced a breaking change (which your PR https://github.com/briannesbitt/Carbon/pull/1190 does not fix).
Example 1:
Carbon::now()->startOfDay()->format('Y-m-d H:i:s u');` // returns '2018-03-12 00:00:00 258223'
Example2:
$from = Carbon::now()->startOfDay();
$to = Carbon::now()->startOfDay();
$date = Carbon::now()->startOfDay();
$date->between($from, $to); // returns false
As I'm using startOfDay() and between() often, you broke all my code with your "minor" update now.
While today() might be easy to fix, the microsecond value being completely immutable affects all methods that use setTime(). One of the most obvious candidates for problems is endOfDay(), as, inevitably, there will be a gap between the "calculated" and the expected value, which for endOfDay() needs to be a microsecond value of 999999.
Imagine checking against entries from a database, to see if an entry has been made today, like this:
$between = $testDate->between($dayStart, $dayEnd);
This, in many cases, will be false, depending solely on the microsecond value of $testDate.
Here's a bit of an example:
$dayStart = Carbon::parse('today'); //to avoid the current "today() problem"
$dayEnd = Carbon::today()->endOfDay();
$randomMicro = str_pad(strval(mt_rand(0, 999999)), 6, '0');
$testDate = new Carbon($dayStart->format('Y-m-d 23:59:59.'.$randomMicro));
//var_dump($testDate);
$between = $testDate->between($dayStart, $dayEnd);
var_dump($between);
In combination with endOfDay() it's currently actually more useful to use today() than parse('today') as this will provide for a smaller chance for something to not match, as otherwise the microsecond value would be 0. This, however, will the result of your patch linked above.
My personal suggestion would be to get rid of the microsecond-code in the current version and leave that for Carbon2, as it's much better supported in PHP 7.1. If you wanted to properly support microseconds in PHP < 7.1 you'd need to store the value in an extra property and adjust a lot of code in order to allow the microsecond value to be changeable.
Your example is not so good as before microseconds were added to "now", a date could be set to 23:59:59.123456 and between($start, $end) could be wrong yet before this change.
The microseconds adding in now() was a very asked feature. If you can make it as mutable, your PR is welcome.
In my code, no date could have been set to _23:59:59.123456_ because I developed it like that. Now you're forcing me to live with this feature (because Laravel predetermines Carbon's version) and I need to adjust my code to work again. That's what I call a breaking change, which would have required a change in the major version.
See this proposition: https://github.com/briannesbitt/Carbon/pull/1190#issuecomment-372579585
You will be able to disable this feature on 1.25 thanks to #1197
Most helpful comment
You will be able to disable this feature on 1.25 thanks to #1197