Datum/tid-värden castas alla till samma basstruktur, det vill säga en DateTime eller DateTimeImmutable objekt, och så naturligt kommer värden endast för datum att läggas till ett tidsvärde (00:00:00 ), och tidsvärden kommer med ett datum (det aktuella datumet).
CakePHP kommer att använda specifika underklasser beroende på SQL-datatypen, det vill säga
\Cake\I18n\Timeeller\Cake\I18n\FrozenTimeunderTIME,TIMESTAMPochDATETIME\Cake\I18n\Dateeller\Cake\I18n\FrozenDateförDATE
I tidigare versioner av CakePHP 3 fanns det bara \Cake\I18n\Time .
Det skulle vara trevligt om det skulle finnas en separat klass för endast tidstypiska typer, som skulle ha ett korrekt standardutmatningsformat för endast tid, men tills något sådant läggs till måste du ta hand om utdataformatet själv .
Formatera i dina vyer
Det är upp till dig hur du ska visa detta i dina vyer. Du kan enkelt använda i18nFormat() metod för Time klassinstans
$record['start_time']->i18nFormat(
[\IntlDateFormatter::NONE, \IntlDateFormatter::SHORT]
)
eller Time hjälpare, för att bara visa tidsdelen
$this->Time->i18nFormat(
$record['start_time'],
[\IntlDateFormatter::NONE, \IntlDateFormatter::SHORT]
)
Antar att det inte skulle skada om bake skulle generera liknande kod beroende på typen av kolumn, du kanske vill föreslå det som en förbättring . Som nämnts kan det också vara värt att överväga att använda ytterligare klasser (eller kanske alternativ) för kolumner med endast tidstyp.
Använd en anpassad tidsklass
Om du hade velat ha det här beteendet överallt där strängrepresentationen av objektet används, utan att manuellt behöva anropa formateraren, kan du använda en utökad \Cake\I18n\Time eller \Cake\I18n\FrozenTime klass med ett åsidosatt $_toStringFormat egenskap, så att den formaterar datumet därefter.
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');
// ...
Detta borde i stort sett vara självförklarande, time kolumner som mappas till TimeType , kommer nu att använda App\I18n\FrozenTimeOnly istället för standard Cake\I18n\Time .
DateTimeType::$dateTimeClass är utfasad
För att klara av det kommer en anpassad databastyp att krävas, vilket också är ganska enkelt.
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);
}
}
Det bör noteras att detta för närvarande kommer att instansiera en data-/tidsklass två gånger, eftersom den överordnade konstruktorn kommer att anropa _setClassName() också, vilket är där en instans av den givna klassen kommer att instansieras.
src/config/bootstrap.php
use App\Database\Type\TimeOnlyType;
Type::map('time', TimeOnlyType::class);
Så vad detta kommer att göra är att åsidosätta standard time typ mappning för att använda den anpassade \App\Database\Type\TimeOnlyType klass, som i sin tur kommer att använda \App\I18n\TimeOnly klass när databasvärden konverteras till PHP-objekt, som när de konverteras till en sträng kommer att använda endast tidsformatet.
Se även
- Kokbok> Tid> Ställa in standardspråk och formatsträng
- Kokbok> Databas Access &ORM> Grundläggande databas> Lägga till anpassade typer