日期/时间值都被转换为相同的基本结构,即DateTime 或DateTimeImmutable 对象,因此自然地仅日期值将添加时间值 (00:00:00),而时间-only 值带有日期(当前日期)。
CakePHP 将根据 SQL 数据类型使用特定的子类,即
-
\Cake\I18n\Time 或 \Cake\I18n\FrozenTime 用于 TIME、TIMESTAMP 和 DATETIME
-
\Cake\I18n\Date 或 \Cake\I18n\FrozenDate 为 DATE
在早期的 CakePHP 3 版本中,只有 \Cake\I18n\Time。
如果有一个单独的类用于仅时间类型会很好,它会设置适当的仅时间默认输出格式,但在添加类似的东西之前,您必须注意自己输出格式。
在您的视图中格式化
如何在视图中显示它取决于您。您可以轻松使用Time 类实例的i18nFormat() 方法
$record['start_time']->i18nFormat(
[\IntlDateFormatter::NONE, \IntlDateFormatter::SHORT]
)
或Time 助手,仅显示时间部分
$this->Time->i18nFormat(
$record['start_time'],
[\IntlDateFormatter::NONE, \IntlDateFormatter::SHORT]
)
如果 bake 会根据列的类型生成类似的代码,你可能想suggest that as an enhancement。如前所述,为仅时间列使用其他类(或选项)可能也值得考虑。
使用自定义时间类
如果您希望在使用对象的字符串表示的任何地方都有这种行为,而不必手动调用格式化程序,那么您可以使用扩展的 \Cake\I18n\Time 或 \Cake\I18n\FrozenTime 类,并覆盖 @ 987654343@ 属性,以便它相应地格式化日期。
src/I18n/FrozenTimeOnly.php
namespace App\I18n;
use Cake\I18n\FrozenTime;
class FrozenTimeOnly extends FrozenTime
{
protected static $_toStringFormat = [
\IntlDateFormatter::NONE,
\IntlDateFormatter::SHORT
];
}
src/config/bootstrap.php
use Cake\Database\Type\TimeType;
use App\I18n\FrozenTimeOnly;
TimeType::$dateTimeClass = FrozenTimeOnly::class;
// remove the default `useImmutable()` call, you may however
// want to keep further calls for formatting and stuff
Type::build('time');
// ...
这应该是不言自明的,被映射到 TimeType 的 time 列现在将使用 App\I18n\FrozenTimeOnly 而不是默认的 Cake\I18n\Time。
DateTimeType::$dateTimeClass 已弃用
为了解决这个问题,需要一个自定义的数据库类型,这也很简单。
src/Database/Type/TimeOnlyType.php
namespace App\Database\Type;
use App\I18n\FrozenTimeOnly;
use Cake\Database\Type\TimeType;
class TimeOnlyType extends TimeType
{
public function __construct($name)
{
parent::__construct($name);
$this->_setClassName(FrozenTimeOnly::class, \DateTimeImmutable::class);
}
}
应该注意的是,目前这将实例化一个数据/时间类两次,因为父构造函数也会调用_setClassName(),这是实例化给定类的实例的地方。
src/config/bootstrap.php
use App\Database\Type\TimeOnlyType;
Type::map('time', TimeOnlyType::class);
因此,这将覆盖默认的 time 类型映射以使用自定义的 \App\Database\Type\TimeOnlyType 类,当将数据库值转换为 PHP 对象时,该类又将使用 \App\I18n\TimeOnly 类,当转换为字符串,将使用仅时间格式。
另见