diff --git a/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php b/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php index 8a49c4a624f0..99456f8bfce7 100644 --- a/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php +++ b/src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php @@ -712,7 +712,7 @@ protected function asDateTime($value) // the database connection and use that format to create the Carbon object // that is returned back out to the developers after we convert it here. return Carbon::createFromFormat( - $this->getDateFormat(), $value + str_replace('.v', '.u', $this->getDateFormat()), $value ); } diff --git a/src/Illuminate/Database/Query/Grammars/SqlServerGrammar.php b/src/Illuminate/Database/Query/Grammars/SqlServerGrammar.php index 858fd4655f80..ec98f935587f 100755 --- a/src/Illuminate/Database/Query/Grammars/SqlServerGrammar.php +++ b/src/Illuminate/Database/Query/Grammars/SqlServerGrammar.php @@ -400,7 +400,7 @@ public function compileSavepointRollBack($name) */ public function getDateFormat() { - return 'Y-m-d H:i:s.000'; + return 'Y-m-d H:i:s.v'; } /** diff --git a/tests/Database/DatabaseEloquentIntegrationTest.php b/tests/Database/DatabaseEloquentIntegrationTest.php index 0ee23bede75a..c5a588000d51 100644 --- a/tests/Database/DatabaseEloquentIntegrationTest.php +++ b/tests/Database/DatabaseEloquentIntegrationTest.php @@ -3,6 +3,7 @@ namespace Illuminate\Tests\Database; use Exception; +use ReflectionObject; use PHPUnit\Framework\TestCase; use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\SoftDeletes; @@ -1138,6 +1139,76 @@ public function testFreshMethodOnCollection() $this->assertEquals($users->map->fresh(), $users->fresh()); } + public function testTimestampsUsingDefaultDateFormat() + { + $model = new EloquentTestUser; + $model->setDateFormat('Y-m-d H:i:s'); // Default MySQL/PostgreSQL/SQLite date format + $model->setRawAttributes([ + 'created_at' => '2017-11-14 08:23:19', + ]); + + $this->assertEquals('2017-11-14 08:23:19.000000', $this->getRawDateTimeString($model->getAttribute('created_at'))); + $this->assertEquals('2017-11-14 08:23:19', $model->fromDateTime($model->getAttribute('created_at'))); + } + + public function testimestampsUsingDefaultSqlServerDateFormat() + { + $model = new EloquentTestUser; + $model->setDateFormat('Y-m-d H:i:s.v'); // Default SQL Server date format + $model->setRawAttributes([ + 'created_at' => '2017-11-14 08:23:19.000', + 'updated_at' => '2017-11-14 08:23:19.734', + ]); + + $this->assertEquals('2017-11-14 08:23:19.000000', $this->getRawDateTimeString($model->getAttribute('created_at'))); + $this->assertEquals('2017-11-14 08:23:19.734000', $this->getRawDateTimeString($model->getAttribute('updated_at'))); + $this->assertEquals('2017-11-14 08:23:19.000', $model->fromDateTime($model->getAttribute('created_at'))); + $this->assertEquals('2017-11-14 08:23:19.734', $model->fromDateTime($model->getAttribute('updated_at'))); + } + + public function testTimestampsUsingCustomDateFormat() + { + // Simulating using custom precisions with timestamps(4) + $model = new EloquentTestUser; + $model->setDateFormat('Y-m-d H:i:s.u'); // Custom date format + $model->setRawAttributes([ + 'created_at' => '2017-11-14 08:23:19.0000', + 'updated_at' => '2017-11-14 08:23:19.7348', + ]); + + $this->assertEquals('2017-11-14 08:23:19.000000', $this->getRawDateTimeString($model->getAttribute('created_at'))); + $this->assertEquals('2017-11-14 08:23:19.734800', $this->getRawDateTimeString($model->getAttribute('updated_at'))); + // Note: when storing databases would truncate the value to the given precision + $this->assertEquals('2017-11-14 08:23:19.000000', $model->fromDateTime($model->getAttribute('created_at'))); + $this->assertEquals('2017-11-14 08:23:19.734800', $model->fromDateTime($model->getAttribute('updated_at'))); + } + + public function testTimestampsUsingOldSqlServerDateFormat() + { + $model = new EloquentTestUser; + $model->setDateFormat('Y-m-d H:i:s.000'); // Old SQL Server date format + $model->setRawAttributes([ + 'created_at' => '2017-11-14 08:23:19.000', + ]); + + $this->assertEquals('2017-11-14 08:23:19.000000', $this->getRawDateTimeString($model->getAttribute('created_at'))); + $this->assertEquals('2017-11-14 08:23:19.000', $model->fromDateTime($model->getAttribute('created_at'))); + } + + /** + * @expectedException \InvalidArgumentException + */ + public function testTimestampsUsingOldSqlServerDateFormatFailInEdgeCases() + { + $model = new EloquentTestUser; + $model->setDateFormat('Y-m-d H:i:s.000'); // Old SQL Server date format + $model->setRawAttributes([ + 'updated_at' => '2017-11-14 08:23:19.734', + ]); + + $attribute = $model->fromDateTime($model->getAttribute('updated_at')); + } + /** * Helpers... */ @@ -1161,6 +1232,11 @@ protected function schema($connection = 'default') { return $this->connection($connection)->getSchemaBuilder(); } + + protected function getRawDateTimeString($object) + { + return (new ReflectionObject($object))->getProperty('date')->getValue($object); + } } /**