Reputation: 4715
I'm trying to get a TimeString from 08:00:00 to 08:00.
I would like to cast time like this:
protected $casts = [
'opens' => 'time:H:i',
'closes' => 'time:H:i',
];
without using mutators like getOpensAttribute().
In my migration I'm using:
$table->time('opens')->nullable();
$table->time('closes')->nullable();
Is it possible?
Upvotes: 11
Views: 14556
Reputation: 2776
i think you can create a custom cast for example:
Generate a custom cast with:
php artisan make:cast TimeCast
TimeCast
public function get($model, string $key, $value, array $attributes)
{
return Carbon::parse($value)->format('H:i');
}
finally you can use it as
protected $casts = [
'your_time_to_cast' => TimeCast::class
];
Upvotes: 13
Reputation: 702
You can achieve this by defining an accessor on your model like so:
protected function opens(): Attribute
{
return Attribute::make(
get: fn($value) => Carbon::createFromFormat('H:i:s', $value)->format('H:i'),
);
}
protected function closes(): Attribute
{
return Attribute::make(
get: fn($value) => Carbon::createFromFormat('H:i:s', $value)->format('H:i'),
);
}
Depending on your needs you might want to also add the name of this attribute to the $appends
property to make it visible when serializing your model:
protected $appends = ['opens', 'closes'];
Please note that my syntax is valid for Laravel version 9+. For older versions, use the below syntax instead:
public function getOpensAttribute($value)
{
return Carbon::createFromFormat('H:i:s', $value)->format('H:i');
}
public function getClosesAttribute($value)
{
return Carbon::createFromFormat('H:i:s', $value)->format('H:i');
}
Upvotes: 1
Reputation: 11
What I ended up doing is overriding toArray() method on the model here's an example from my code from inside the model file
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class City extends Model
{
use HasFactory;
/**
* The attributes that are mass assignable.
*
* @var array
*/
protected $fillable = [
'name',
];
/* this is the related part */
public function toArray()
{
$array = parent::toArray();
$array['starts_at'] = $array['starts_at']->format('H:i:s');
$array['ends_at'] = $array['ends_at']->format('H:i:s');
return $array;
}
}
Upvotes: 0
Reputation: 423
According to the docs, the only supported cast types are:
integer, real, float, double, string, boolean, object, array, collection, date, datetime, and timestamp.
Therefore you have to convert your time to string either before you store it or after you retrieve it from the database.
Upvotes: 1