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\Time
eller\Cake\I18n\FrozenTime
underTIME
,TIMESTAMP
ochDATETIME
\Cake\I18n\Date
eller\Cake\I18n\FrozenDate
fö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