Laravel 表单模型绑定日期
Laravel dates on form model binding
我正在使用 Laravel 5.1
我得到了一个模型:
class ExampleModel extends Model {
// ....
protected $dateFormat = 'Y.m.d';
protected $dates = ['first_date', 'second_date'];
// ...
}
所以当我索引 ExampleModel 元素时,日期格式是正确的(例如 2015.07.31)
但在编辑表单上它使用默认格式:2015-07-31 00:00:00
我正在使用 Form::model()
绑定。
我知道我可以使用 getFirstDateAttribute()
但这不是我正在寻找的解决方案。因为它一点也不优雅,一旦我定义了 $dates
数组,它应该在每种情况下自动工作。
所以这可能是一个错误?还是我做错了什么?
我以前从未这样做过,但它似乎适用于我放在一起的一个基本示例。请注意,我只是在表单开始标记中调用模型上的 toArray
方法。
{!! Form::model($exampleModel->toArray(), ['route' => ['example-models.update', $exampleModel->id]]) !!}
{!! Form::label('first_date', 'First Date') !!}
{!! Form::text('first_date') !!}
{!! Form::close() !!}
文档说 dateFormat
属性 决定了将对象转换为 json 或数组时的日期格式。
我通过覆盖 Carbon 的默认日期格式解决了我的问题:
Carbon\Carbon::setToStringFormat('Y.m.d');
但是凯利的回答更好更优雅,我只是post这个,也许有人会觉得这个有用一次。
我不完全建议将此作为修复,因为当您更新核心时,您将失去此修复,但也许应该将其作为拉取请求发布到 Laravel'下一个版本。
在 \Illuminate\Database\Eloquent\Concerns\HasAttributes 中更新 asDate 函数如下。正如您从评论中看到的那样,asDate 函数仍然是 returns 时间戳,即使它是 00:00:00.
/**
* Return a timestamp as DateTime object with time set to 00:00:00.
*
* @param mixed $value
* @return \Illuminate\Support\Carbon
*/
protected function asDate($value)
{
$date = $this->asDateTime($value)->startOfDay();
$date->setToStringFormat($this->getDateFormat());
return $date;
}
这允许您控制模型中日期的格式(注意我区分的是日期和日期时间)。然后使用 casts 变量将变量转换为日期格式。
protected $casts = [
'start_date' => 'date',
'end_date' => 'date'
];
protected $dateFormat = 'Y-m-d';
$dates 变量无法区分日期和日期时间。
更新
真正的问题是表单模型绑定跳过了 FormBuilder class 的辅助函数。如您所见,如果您检查 \Collective\Html\FormBuilder::date
/**
* Create a date input field.
*
* @param string $name
* @param string $value
* @param array $options
*
* @return \Illuminate\Support\HtmlString
*/
public function date($name, $value = null, $options = [])
{
if ($value instanceof DateTime) {
$value = $value->format('Y-m-d');
}
return $this->input('date', $name, $value, $options);
}
按照 HTML5 规范中的规定,正确地将日期格式化为 'Y-m-d'。然而此时 $value 实际上是空的。所以你必须更新通用输入功能。
/**
* Create a form input field.
*
* @param string $type
* @param string $name
* @param string $value
* @param array $options
*
* @return \Illuminate\Support\HtmlString
*/
public function input($type, $name, $value = null, $options = [])
{
...
//$value is null here
if (! in_array($type, $this->skipValueTypes)) {
//$value is fetched based on hierarchy set by
$value = $this->getValueAttribute($name, $value);
//necessary duplicate code to format date value
if ($type == 'date' && $value instanceof DateTime) {
$value = $value->format('Y-m-d');
}
}
...
}
UPDATE 无需更新供应商代码。查看 FormModelAccessors
https://laravelcollective.com/docs/5.2/html#form-model-binding
我正在使用 Laravel 5.1
我得到了一个模型:
class ExampleModel extends Model {
// ....
protected $dateFormat = 'Y.m.d';
protected $dates = ['first_date', 'second_date'];
// ...
}
所以当我索引 ExampleModel 元素时,日期格式是正确的(例如 2015.07.31)
但在编辑表单上它使用默认格式:2015-07-31 00:00:00
我正在使用 Form::model()
绑定。
我知道我可以使用 getFirstDateAttribute()
但这不是我正在寻找的解决方案。因为它一点也不优雅,一旦我定义了 $dates
数组,它应该在每种情况下自动工作。
所以这可能是一个错误?还是我做错了什么?
我以前从未这样做过,但它似乎适用于我放在一起的一个基本示例。请注意,我只是在表单开始标记中调用模型上的 toArray
方法。
{!! Form::model($exampleModel->toArray(), ['route' => ['example-models.update', $exampleModel->id]]) !!}
{!! Form::label('first_date', 'First Date') !!}
{!! Form::text('first_date') !!}
{!! Form::close() !!}
文档说 dateFormat
属性 决定了将对象转换为 json 或数组时的日期格式。
我通过覆盖 Carbon 的默认日期格式解决了我的问题:
Carbon\Carbon::setToStringFormat('Y.m.d');
但是凯利的回答更好更优雅,我只是post这个,也许有人会觉得这个有用一次。
我不完全建议将此作为修复,因为当您更新核心时,您将失去此修复,但也许应该将其作为拉取请求发布到 Laravel'下一个版本。
在 \Illuminate\Database\Eloquent\Concerns\HasAttributes 中更新 asDate 函数如下。正如您从评论中看到的那样,asDate 函数仍然是 returns 时间戳,即使它是 00:00:00.
/**
* Return a timestamp as DateTime object with time set to 00:00:00.
*
* @param mixed $value
* @return \Illuminate\Support\Carbon
*/
protected function asDate($value)
{
$date = $this->asDateTime($value)->startOfDay();
$date->setToStringFormat($this->getDateFormat());
return $date;
}
这允许您控制模型中日期的格式(注意我区分的是日期和日期时间)。然后使用 casts 变量将变量转换为日期格式。
protected $casts = [
'start_date' => 'date',
'end_date' => 'date'
];
protected $dateFormat = 'Y-m-d';
$dates 变量无法区分日期和日期时间。
更新 真正的问题是表单模型绑定跳过了 FormBuilder class 的辅助函数。如您所见,如果您检查 \Collective\Html\FormBuilder::date
/**
* Create a date input field.
*
* @param string $name
* @param string $value
* @param array $options
*
* @return \Illuminate\Support\HtmlString
*/
public function date($name, $value = null, $options = [])
{
if ($value instanceof DateTime) {
$value = $value->format('Y-m-d');
}
return $this->input('date', $name, $value, $options);
}
按照 HTML5 规范中的规定,正确地将日期格式化为 'Y-m-d'。然而此时 $value 实际上是空的。所以你必须更新通用输入功能。
/**
* Create a form input field.
*
* @param string $type
* @param string $name
* @param string $value
* @param array $options
*
* @return \Illuminate\Support\HtmlString
*/
public function input($type, $name, $value = null, $options = [])
{
...
//$value is null here
if (! in_array($type, $this->skipValueTypes)) {
//$value is fetched based on hierarchy set by
$value = $this->getValueAttribute($name, $value);
//necessary duplicate code to format date value
if ($type == 'date' && $value instanceof DateTime) {
$value = $value->format('Y-m-d');
}
}
...
}
UPDATE 无需更新供应商代码。查看 FormModelAccessors
https://laravelcollective.com/docs/5.2/html#form-model-binding