diff --git a/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php b/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php index 1e57c91004d8..8d329f106293 100644 --- a/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php +++ b/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php @@ -761,7 +761,9 @@ public function setAttribute($key, $value) // If an attribute is listed as a "date", we'll convert it from a DateTime // instance into a form proper for storage on the database tables using // the connection grammar's date format. We will auto set the values. - elseif ($value && $this->isDateAttribute($key)) { + elseif ($value && $this->isDateAttribute($key) && !( + $this->hasCast($key, ['custom_datetime', 'immutable_custom_datetime']) && is_string($value) + )) { $value = $this->fromDateTime($value); } @@ -1643,7 +1645,7 @@ public function originalIsEquivalent($key) return true; } elseif (is_null($attribute)) { return false; - } elseif ($this->isDateAttribute($key) || $this->isDateCastable($key)) { + } elseif ($this->isDateAttribute($key)) { return $this->fromDateTime($attribute) === $this->fromDateTime($original); } elseif ($this->hasCast($key, ['object', 'collection'])) { diff --git a/tests/Integration/Database/EloquentModelDateCastingTest.php b/tests/Integration/Database/EloquentModelDateCastingTest.php index 474c5a6e508a..e023bcefc0a3 100644 --- a/tests/Integration/Database/EloquentModelDateCastingTest.php +++ b/tests/Integration/Database/EloquentModelDateCastingTest.php @@ -40,7 +40,46 @@ public function testDatesAreCustomCastable() $this->assertInstanceOf(Carbon::class, $user->datetime_field); } - public function testCustomDateCastsAreComparedAsDates() + public function testDatesFormattedAttributeBindings() + { + $bindings = []; + + $this->app->make('db')->listen(static function ($query) use (&$bindings) { + $bindings = $query->bindings; + }); + + $user = TestModel1::create([ + 'date_field' => '2019-10', + 'datetime_field' => new CarbonImmutable('2019-10-01 10:15:20'), + 'immutable_date_field' => new CarbonImmutable('2019-10-01'), + 'immutable_datetime_field' => '2019-10-01 10:15', + ]); + + $this->assertSame(['2019-10', '2019-10-01 10:15:20', '2019-10-01 00:00:00', '2019-10-01 10:15'], $bindings); + } + + public function testCustomDateCastsAreComparedAsDatesForStringValues() + { + /** @var TestModel1 */ + $user = TestModel1::create([ + 'date_field' => '2019-10-01', + 'datetime_field' => '2019-10-01 10:15:20', + 'immutable_date_field' => '2019-10-01', + 'immutable_datetime_field' => '2019-10-01 10:15:20', + ]); + + $user->date_field = '2019-10-01'; + $user->datetime_field = '2019-10-01 10:15:20'; + $user->immutable_date_field = '2019-10-01'; + $user->immutable_datetime_field = '2019-10-01 10:15:20'; + + $this->assertArrayNotHasKey('date_field', $user->getDirty()); + $this->assertArrayNotHasKey('datetime_field', $user->getDirty()); + $this->assertArrayNotHasKey('immutable_date_field', $user->getDirty()); + $this->assertArrayNotHasKey('immutable_datetime_field', $user->getDirty()); + } + + public function testCustomDateCastsAreComparedAsDatesForCarbonValues() { /** @var TestModel1 */ $user = TestModel1::create([