场景
我的start
类型的实体中有end
和DateTime
字段。
/**
* @ORM\Column(type="datetime")
* @var \DateTime
*/
private $start;
/**
* @ORM\Column(type="datetime", nullable=true)
* @var \DateTime
*/
private $end;
我只想修改这些值的时间,所以我用这样的字段声明构建了一个表单:
->add('start', TimeType::class, [
'widget' => 'single_text',
])
->add('end', TimeType::class, [
'widget' => 'single_text',
])
样本值
更新前这些字段的样本值(格式:'Y-m-d h:i:s
'):2018-07-01 17:30:00
表单输入
17:50
预期结果
2018-07-01 17:50:00
实际结果
1970-01-01 17:50:00
有没有一种方法可以使用表单仅显示和修改DateTime对象的时间部分,而无需触摸日期部分?
答案 0 :(得分:1)
理论上,您将需要编写自己的数据转换器,该转换器将接受您的输入,验证特定字段并将其与现有数据合并。您还需要解决一个极端的情况,即有人提交了time
,但当时的现有数据为空。
从外观上看,目前没有满足您要求的变压器,但是编写您自己的变压器相对容易。我看到的问题是,您将需要使转换器知道模型数据并将合并的数据与现有数据合并。对我来说,这将是不良设计和明显违反责任的标志。
如果您仍然愿意,可以查看以下内容:
和现有的日期转换器之一:
但是,我的方法是监听特定字段上的SUBMIT
事件并拦截提交的数据。
这是我设法快速编写的示例:
$inData = [
'start_date' => new \DateTime(),
];
// Shows local date: 2018-07-07 23:28
dump($inData);
$form = $this->createForm(PartialTimeType::class, $inData);
$form->submit([
'start_date' => '23:50',
]);
$outData = $form->getData();
// Should show 2018-07-07 23:50
dump($outData);
PartialTimeType:
$builder
->add('start_date', TimeType::class, [
'label' => 'Start time',
'widget' => 'single_text'
]);
$builder->get('start_date')->addEventListener(FormEvents::SUBMIT, function (FormEvent $event) {
/** @var \DateTime $modelData */
$modelData = $event->getForm()->getData();
/** @var \DateTime $data */
$data = $event->getData();
$data->setDate(
(int)$modelData->format('Y'),
(int)$modelData->format('m'),
(int)$modelData->format('d')
);
});
我确信您可以编写自己的TimeType
扩展名,该扩展名将这种行为封装为box ...
希望这对您有帮助...