Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/Illuminate/Database/Eloquent/Concerns/HasAttributes.php
Original file line number Diff line number Diff line change
Expand Up @@ -508,6 +508,8 @@ protected function castAttribute($key, $value)
case 'datetime':
case 'custom_datetime':
return $this->asDateTime($value);
case 'time':
return $this->asTime($value);
case 'timestamp':
return $this->asTimestamp($value);
default:
Expand Down Expand Up @@ -837,6 +839,19 @@ public function fromDateTime($value)
);
}

/**
* Return a timestamp as DateTime object with the current date.
*
* @param mixed $value
* @return false|\Illuminate\Support\Carbon
*/
protected function asTime($value)
{
return $value instanceof CarbonInterface
? Date::instance($value)
: Date::createFromFormat('H:i:s', $value)->startOfSecond();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added a microsecond reset because without it the time comparison would be wrong.

The TIME field type of the database does not store information about milliseconds, and when the now () functions are called in sequence, the values will be different.
The startOfSecond () method leads them to a single value, as a result of which the comparison will be correct.

The result of the verification showed here: #30931 (review)

}

/**
* Return a timestamp as unix timestamp.
*
Expand Down
47 changes: 47 additions & 0 deletions tests/Integration/Database/EloquentModelTimeCastingTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
<?php

namespace Illuminate\Tests\Integration\Database;

use Carbon\Carbon;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class EloquentModelTimeCastingTest extends DatabaseTestCase
{
public function testTimesAreCastable()
{
$item = TestTimeModel::create([
'time_field' => '08:11:27',
]);

$this->assertEquals(date_create('08:11:27'), $item->time_field);
$this->assertEquals(date_create('08:11:27'), $item->toArray()['time_field']);
$this->assertSame('08:11:27', $item->time_field->format('H:i:s'));
$this->assertSame('08:11', $item->time_field->format('H:i'));
$this->assertInstanceOf(Carbon::class, $item->time_field);
}

protected function setUp(): void
{
parent::setUp();

Schema::create('test_model1', function (Blueprint $table) {
$table->increments('id');
$table->time('time_field')->nullable();
});
}
}

class TestTimeModel extends Model
{
public $timestamps = false;

protected $table = 'test_model1';

protected $guarded = ['id'];

protected $casts = [
'time_field' => 'time',
];
}