Fro*_*gyp 5 datetime cakephp marshalling internationalization cakephp-3.0
我尝试从cakephp 3表单中保存数据.所有数据都保存得很好,但日期时间没有.我有2个日期时间字段.这些字段由jquery-ui小部件填充.
在实体化时,似乎发生了这个问题.
$intervention = $this->Interventions->patchEntity($intervention, $this->request->data);
Run Code Online (Sandbox Code Playgroud)
调试$ this-> request-> data:
'user_id' => '1',
'description' => 'test',
'starttime' => '2015/11/15 10:00',
'endtime' => '2015/11/15 12:10'
Run Code Online (Sandbox Code Playgroud)在pacthEntity之后调试我的对象$干预:
对象(应用程序\模型\实体\干预)
'id' => (int) 3,
'user_id' => (int) 1,
'description' => 'test',
'starttime' => null,
'endtime' => null
...
Run Code Online (Sandbox Code Playgroud)
starttime和endtime变为null,我不明白为什么.
有人曾经有过这个pb吗?
我尝试(用于调试和理解)强制字段值,然后在mysql中修补和datetime字段都可以.
$intervention->starttime = date('Y-m-d H:i:s', strtotime($this->request->data['starttime']));
$intervention->endtime = date('Y-m-d H:i:s', strtotime($this->request->data['endtime']));
Run Code Online (Sandbox Code Playgroud)
感谢帮助
ndm*_*ndm 20
更新:这是3.2.5之前的CakePHP应用程序模板版本的默认行为.从3.2.5开始,默认情况下不再启用语言环境解析,这将使日期/时间编组逻辑期望默认格式Y-m-d H:i:s.
在编组过程中,根据相应的列类型对值进行"转换".对于DATETIME列,这是由\Cake\Database\Type\DateTimeType类型类完成的.
确切地说,这是完成的\Cake\Database\Type\DateTimeType::marshall().
使用默认的应用程序模板配置,DateTimeType配置为使用区域设置感知解析,并且由于没有设置默认的区域设置格式,因此 \Cake\I18n\Time::parseDateTime()将根据其默认的"字符串格式"(Time::$_toStringFormat)来解析值,默认情况下可识别区域设置[IntlDateFormatter::SHORT, IntlDateFormatter::SHORT].
因此,如果您的语言环境设置为en_US,那么该值将使用M/d/yy, h:mm a您的值不适合的预期格式进行解析,因此您最终将最终null设置为实体属性.
TL;博士
如果jQuery小部件的格式没有在您的应用程序中的任何位置使用,您可以例如临时设置正确的区域设置格式,或者禁用区域设置解析,例如
// for time- or date-only comlumn types you'd use 'time' or 'date' instead of 'datetime'
$dateTimeType = Type::build('datetime')->setLocaleFormat('yyyy/MM/dd HH:mm');
// ...
$intervention = $this->Interventions->patchEntity($intervention, $this->request->data);
// ...
$dateTimeType->setLocaleFormat(null);
Run Code Online (Sandbox Code Playgroud)
要么
$dateTimeType = Type::build('datetime')->useLocaleParser(false);
// ...
$intervention = $this->Interventions->patchEntity($intervention, $this->request->data);
// ...
$dateTimeType->useLocaleParser(true);
Run Code Online (Sandbox Code Playgroud)
应该注意,这将影响所有日期/时间输入,而不仅仅是你的starttime和endtime字段!
另一方面,jQuery小部件使用的格式应该是您希望在应用程序中使用的格式,那么更改默认格式也可以这样做,例如
use Cake\I18n\Time;
use Cake\I18n\FrozenTime;
// To affect date-only columns you'd configure `Date` and `FrozenDate`.
// For time-only columns, see the linked SO question below.
Time::setToStringFormat('yyyy/MM/dd HH:mm');
FrozenTime::setToStringFormat('yyyy/MM/dd HH:mm');
Run Code Online (Sandbox Code Playgroud)
在你的bootstrap.php.请注意,这里还有Time/FrozenTime::setJsonEncodeFormat()和Time/FrozenTime::$niceFormat你可能想/需要修改了.
也可以看看
另一种选择是Time例如在编组过程之前将数据转换为实例.这将避免前面提到的可能影响所有输入的解决方案的可能问题.
在您的InterventionsTable课程中(也可以放入行为或外部监听器):
use Cake\Event\Event;
use Cake\I18n\Time;
...
public function beforeMarshal(Event $event, \ArrayObject $data, \ArrayObject $options)
{
foreach (['starttime', 'endtime'] as $key) {
if (isset($data[$key]) && is_string($data[$key])) {
$data[$key] = Time::parseDateTime($data[$key], 'yyyy/MM/dd HH:mm');
}
}
}
Run Code Online (Sandbox Code Playgroud)
也可以看看
Cookbook>数据库访问和ORM>保存数据>在构建实体之前修改请求数据