Laravel 中的 Carbon 意外日期时间格式

clz*_*ola 5 php datetime laravel php-carbon laravel-5

Carbon我对HTML5 输入有问题input[type=datetime-local],因为此输入以格式Y-m-d\TH:i(例如2016-11-20T11:45)发送数据时间。

我的控制器中有方法:

public function store(ModelStoreFormRequest $request) 
{
    $model = new Model($request->all());
    $model->save();
    return redirect->action(/*...*/);
}
Run Code Online (Sandbox Code Playgroud)

我得到例外:

InvalidArgumentException in Carbon.php line 582: Data Missing
1. in Carbon.php line 582
2. at Carbon::createFromFormat('Y-m-d H:i:s', '2016-11-20T11:45') in HasAttributes.php line 709
Run Code Online (Sandbox Code Playgroud)

所以我通过在模型中创建下一个函数解决了这个问题:

public function setStartedAtAttribute($startedAt)
{
    if( $startedAt instanceof Carbon ) {
        $this->attributes['started_at'] = $startedAt;
        return;
    }

    if( strpos($startedAt, 'T' ) ) {
        $this->attributes['started_at'] = Carbon::createFromFormat('Y-m-d\TH:i', $startedAt);
        return;
    }

    $this->attributes['started_at'] = Carbon::createFromFormat('Y-m-d H:i:s', $startedAt);
}
Run Code Online (Sandbox Code Playgroud)

但我不喜欢这个解决方案,不知道是否有更优雅的解决方案?我正在考虑使用ModelStoreFormRequest::prepareForValidation()方法来检查日期格式是否为:Y-m-d\TH:i将日期时间值更改为格式:Y-m-d H:i:s,或者可能使用Carbon::parse()这样的方法:

protected function prepareForValidation() 
{
    $input = $this->all();
    $input['started_at'] = \Carbon\Carbon::parse($input['started_at']);
    $this->replace($input);
}
Run Code Online (Sandbox Code Playgroud)

但我仍然不知道这个解决方案好吗。我试图将每个班级的关注点和义务分开......你有什么建议?还有其他更优雅的解决方案还是坚持当前的解决方案?

Mr.*_*mid 6

尝试这个简单的解决方案,而不是创建自定义函数来更改格式或编辑 Laravel 的任何基础

$startedAt= Carbon::createFromFormat('Y-m-d\TH:i','2016-11-20T11:45');
Run Code Online (Sandbox Code Playgroud)

将返回给您:

2016-11-20 11:45:00
Run Code Online (Sandbox Code Playgroud)

现在,对于您关心的问题,如果您将来在多个地方不需要它,我会建议您在控制器中使用它。

如果您需要以该格式将日期存储到数据库中并且不需要在像这样的多个地方使用,您也可以将其用作模型中的变异器

变异者

public static $snakeAttributes = false; // because you have camel case here
public function setStartedAtAttribute($value)
{
    $this->attributes['startedAt'] = Carbon::createFromFormat('Y-m-d\TH:i',$value);;
}
Run Code Online (Sandbox Code Playgroud)

配件

public function getStartedAtAttribute()
    {
        $startedAt = $this->attributes['startedAt'];
        return $startedAt
    }
Run Code Online (Sandbox Code Playgroud)

如果您需要在多个地方使用您的函数,您可以为您的函数创建一个单独的特征,我建议这是最佳实践。

trait YourTraitName{
  public function yourfunction(){
$startedAt= Carbon::createFromFormat('Y-m-d\TH:i','2016-11-20T11:45');
return $startedAt;
    }
}
Run Code Online (Sandbox Code Playgroud)

排除中间件,中间件通常用于身份验证检查,请阅读有关中间件的更多信息

更多Carbon相关操作可以阅读这里并在这里测试