Laravel:如何在模型属性转换中设置日期格式?

49

我在模型中有:

protected $casts = [
    'date' => 'date',
];

Laravel有没有设置类型转换格式的能力,例如:

protected $casts = [
    'date' => 'date_format:d/m/yyyy',
];

?

已编辑

我尝试了这个:

在模型中:

protected $dateFormat = 'm/d/Y';

protected $dates = ['driver_expiration', 'created_at', 'updated_at', 'deleted_at'];

protected $casts = [
    'driver_expiration'     => 'date',
];

我将日期(driver_expiration)保存为'01/012016',但实际上保存的是0000-00-00。

Laravel文档: https://laravel.com/docs/5.1/eloquent-mutators 告诉我们$dateFormat仅适用于时间戳('created_at','updated_at','deleted_at')。

8个回答

107

在 Laravel 5.6 之后,您可以单独自定义 Eloquent 日期和日期时间的转换格式:

protected $casts = [
    'birthday'  => 'date:Y-m-d',
    'joined_at' => 'datetime:Y-m-d H:00',
];

当模型被序列化为数组或JSON数据时,使用此格式。


我已经在模型中添加了上述代码,并将格式更改为“date:m-d-Y”,但是Eloquent的find方法返回的结果却是m-d-y。请建议。 - Kamlesh
如何在 protected $dates Carbon 类型声明中使用强制类型转换? - Yevgeniy Afanasyev
文档可在此处查看:Laravel 5.6+Laravel 6.x - David Rodrigues

47

不必强制转换日期格式,您可以使用修改器设置所需的格式:

例如,如果您的列名为date,则可以将以下函数添加到您的模型中:

public function setDateAttribute( $value ) {
  $this->attributes['date'] = (new Carbon($value))->format('d/m/y');
}

setDateAttribute 的格式始终为 set[ColumnName]Attribute,使用 CamelCase。在 $this->attributes['date'] 部分的 date 也必须匹配表格中实际列名。

当您在数据库中 createupdate 记录时,上述函数会自动更改格式。

注意:您可能需要在模型顶部添加 use Carbon\Carbon 语句来使用 Carbon 库。

在此处查看其他示例


更新

可选地,您可以使用以下方式为 date 列定义格式:

protected $dateFormat = 'Y-m-d';

6
我不想要一千个变异器,也不想重复代码...... 数组更加优雅实用。 - fico7489
@fico7489,你也可以使用模型的日期格式,而默认情况下无法在转换中实现这一点。 - GONG
这里是证据,@fico7489 https://github.com/illuminate/database/blob/5.1/Eloquent/Model.php#L2796,看起来casts使用`$dateFormat`进行格式化。 - GONG
“优雅实用”就这样了。使用mutators会更容易。 - Niraj Shah
你最不想要做的就是在数据模型里面添加没必要的代码。通过转换类型,你可以达到同样的效果。 - Jed Lynch

12

只需将其添加到模型中:

protected function asDateTime($value)
{
    return parent::asDateTime($value)->format('d/m/y');
}

这个Eloquent的方法最初返回一个Carbon实例,因此你可以获取该实例并调用它的format()方法。如果你希望将此解决方案应用于所有模型,只需创建一个从Eloquent扩展的新类,并将此方法放在其中,然后你可以从这个新类中扩展模型。

1
在所有的答案中,这是唯一一个对我来说在 Laravel 8 中可行的。 - Willi
谢谢您的回答!在没有访问器或任何自定义函数的情况下,转换格式/时区的最佳方法。 - keviveks
同时,在 Laravel 10 上添加 protected $casts 变量,也可以让它正常工作。 - MAHA OUEGHLANI

4

对于我来说,我只需将以下代码放入我的Model中,就可以格式化所有日期。

protected function serializeDate($date)
{
    return $date->format('Y-m-d H:i:s');
}

2

我创建了一个新的模型属性:

protected $datesConvert = ['driver_expiration'];

然后我更新了我的基础模型,如下所示:

public function save(array $options = [])
{
    if(isset($this->datesConvert)){
        foreach($this->datesConvert as $date){
            $this->attributes[$date] = \Carbon\Carbon::createFromFormat('d/m/Y', $this->attributes[$date])->format('Y-m-d');
        }
    }

    parent::save($options);

}

public function getAttribute($key)
{
    $value = parent::getAttribute($key);

    if(isset($this->attributes[$key])){
        if(isset($this->datesConvert)  &&  in_array($key, $this->datesConvert)){
            $value = \Carbon\Carbon::createFromFormat('Y-m-d', $value)->format('d/m/Y');
        }

    }

    return $value;
}

这个解决方案对我很有用。代码可以移到trait中。格式可以放在$datesConvert格式=“d/m/Y”中。


1
集合对象不会影响演员阵容。它用于json和数组格式。如果您需要一个单独的演员阵容,则可以使用。
 $user->date->format('m-d-Y');

0

试试这个:

//Note: Add this Carbon library at the top of your Model. 
use Carbon\Carbon
    
public function getDateAttribute($date)
        {
            return $this->attributes['date'] = Carbon::parse($date)->format('d/m/Y');
        }

0

Laravel 10.x

在模型中

use Illuminate\Database\Eloquent\Casts\Attribute;

protected function createdAt(): Attribute
{
    return Attribute::make(
        get: fn ($value, $attributes) => Carbon::create($value)->format(m/d/Y")
    );
}

1
如果你需要转换很多日期,使用mutators是不切实际的。 - MAHA OUEGHLANI

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接