Всички стойности за дата/час се прехвърлят към една и съща базова структура, тоест DateTime
или DateTimeImmutable
обект и така естествено стойностите само за дата ще имат добавена стойност за време (00:00:00
), а стойностите само за време идват с дата (текущата дата).
CakePHP ще използва специфични подкласове в зависимост от SQL типа данни, тоест
\Cake\I18n\Time
или\Cake\I18n\FrozenTime
заTIME
,TIMESTAMP
иDATETIME
\Cake\I18n\Date
или\Cake\I18n\FrozenDate
заDATE
В по-ранните версии на CakePHP 3 имаше само \Cake\I18n\Time
.
Би било хубаво да има отделен клас за типове само за време, който да има правилен зададен изходен формат само за време, но докато не се добави нещо подобно, ще трябва сами да се погрижите за изходния формат .
Форматирайте във вашите изгледи
От вас зависи как да покажете това във вашите изгледи. Можете лесно да използвате i18nFormat()
метод на Time
екземпляр на клас
$record['start_time']->i18nFormat(
[\IntlDateFormatter::NONE, \IntlDateFormatter::SHORT]
)
или Time
помощник, за да се покаже само частта от времето
$this->Time->i18nFormat(
$record['start_time'],
[\IntlDateFormatter::NONE, \IntlDateFormatter::SHORT]
)
Предполагам, че няма да навреди, ако bake генерира подобен код според типа колона, може да искате да предложете това като подобрение . Както споменахме, използването на допълнителни класове (или може би опции) за колони само за време може също да е нещо, което си струва да се обмисли.
Използвайте персонализиран времеви клас
Ако искате това поведение навсякъде, където се използва низовото представяне на обекта, без да се налага ръчно да извиквате формататора, тогава можете да използвате разширен \Cake\I18n\Time
или \Cake\I18n\FrozenTime
клас с отменен $_toStringFormat
свойство, така че да форматира съответно датата.
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');
// ...
Това до голяма степен трябва да се разбира от само себе си, time
колони, които се съпоставят с TimeType
, вече ще използва 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
клас, който от своя страна ще използва \App\I18n\TimeOnly
клас при конвертиране на стойности на базата данни в PHP обекти, които при преобразуване в низ ще използват формата само за време.
Вижте също
- Готварска книга> Време> Задаване на локален език по подразбиране и низ за формат
- Готварска книга> База данни Достъп и ORM> Основи на базата данни> Добавяне на персонализирани типове