日期/时间值正在以区域设置感知的方式进行转换/解析
更新:这是 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;dr
如果 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);
or
$dateTimeType = Type::build('datetime')->useLocaleParser(false);
// ...
$intervention = $this->Interventions->patchEntity($intervention, $this->request->data);
// ...
$dateTimeType->useLocaleParser(true);
需要注意的是,这会影响all日期/时间输入,不仅仅是您的starttime
and endtime
fields!
另一方面,如果 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');
in your bootstrap.php
。请注意,还有Time/FrozenTime::setJsonEncodeFormat()
and Time/FrozenTime::$niceFormat
您可能也想/需要修改它。
See also
- Cookbook > 国际化和本地化 > 解析本地化日期时间数据
- Cookbook > 时间 > 设置默认区域设置和格式字符串
- CakePHP 3时间列获取添加日期
在编组之前转换输入
另一种选择是将数据转换为Time
编组过程之前的实例。这将避免前面提到的解决方案可能出现影响所有输入的问题。
In your 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');
}
}
}
See also
Cookbook > 数据库访问和 ORM > 保存数据 > 在构建实体之前修改请求数据