framework: DateTime Precision is lost when adding date to model factories
- Laravel Version: v5.6.17
- PHP Version: 7.1.17
Description:
When using a model factory with a fixed date the microseconds are lost. This means when asserting in a unit test dates do not match when they should.
Steps To Reproduce:
public function some_test() {
Carbon::setTestNow(new Carbon());
$t = factory(Model::class)->make(['date_field' => Carbon::now()->addWeeks(2)]);
$this->assertEquals($t->date_field, Carbon::now()->addWeeks(2));
}
Failed asserting that two DateTime objects are equal. — Expected +++ Actual @@ @@ -2018-05-28T21:53:00.000000+0000 +2018-05-28T21:53:00.613965+0000
About this issue
- Original URL
- State: closed
- Created 6 years ago
- Reactions: 2
- Comments: 27 (21 by maintainers)
The microseconds are removed by
HasAttributes::setAttribute()
, which uses the database connection’s default date format. With the exception of SQL Server, this is alwaysY-m-d H:i:s
.You can specify a custom format in your model:
@driesvints Yes, this is working in PHP 7.3.
It looks like we can’t really support microseconds on MySQL at the moment.
Saving works, but fetching doesn’t: There is a four-year-old bug that removes microseconds when using
PDO::ATTR_EMULATE_PREPARES => false
(which Laravel does by default).Technically we are no worse off than before. We’ve always dropped the microseconds - its not a new bug.
The issue is Carbon tests will just “highlight” the issue now.
So it would seem like something worth targeting for 5.7 to change and incorporate microseconds (if at all).
Seems like the https://github.com/php/php-src/pull/3257 was merged for the 7.3 release. If anyone can verify if this is fixed for the latest 7.3 RC that’d be great.
I’m going to close this because this seems to be related to PHP rather than Laravel. People can still find this issue in the tracker.
@sisve I am not totally sure of that being true. I am uncertain about the factory helper stuff, but we definitely use Laravel/Eloquent with timestamps and Carbon and it definitely produced an issue exactly like this one in appearance until we turned PDO::ATTR_EMULATE_PREPARES on.
@a-komarev That PR may fix some related problems, but that PR alone will not fix this issue. Laravel still formats date fields using the query grammar’s date format, and it doesn’t support milli-/microseconds.