Os valores de data/hora estão sendo convertidos para a mesma estrutura base, que é um
DateTime
ou DateTimeImmutable
e, portanto, valores somente de data terão um valor de hora adicionado (00:00:00
), e os valores somente de hora vêm com uma data (a data atual). O CakePHP usará subclasses específicas dependendo do tipo de dados SQL, ou seja,
\Cake\I18n\Time
ou\Cake\I18n\FrozenTime
porTIME
,TIMESTAMP
eDATETIME
\Cake\I18n\Date
ou\Cake\I18n\FrozenDate
paraDATE
Nas versões anteriores do CakePHP 3 havia apenas
\Cake\I18n\Time
. Seria bom se houvesse uma classe separada para tipos somente de tempo, que teria um formato de saída padrão somente de tempo adequado, mas até que algo assim seja adicionado, você terá que cuidar do formato de saída você mesmo .
Formatar em suas visualizações
Cabe a você como exibir isso em suas visualizações. Você pode facilmente usar o
i18nFormat()
método do Time
instância de classe $record['start_time']->i18nFormat(
[\IntlDateFormatter::NONE, \IntlDateFormatter::SHORT]
)
ou o
Time
auxiliar, para mostrar apenas a parte do tempo $this->Time->i18nFormat(
$record['start_time'],
[\IntlDateFormatter::NONE, \IntlDateFormatter::SHORT]
)
Acho que não faria mal se o bake gerar um código semelhante de acordo com o tipo de coluna, você pode querer sugerir isso como um aprimoramento . Como mencionado, usar classes adicionais (ou talvez opções) para colunas somente de tempo pode ser algo que vale a pena considerar também.
Use uma classe de tempo personalizada
Se você quisesse esse comportamento em todos os lugares em que a representação de string do objeto estivesse sendo usada, sem precisar invocar manualmente o formatador, você poderia usar um
\Cake\I18n\Time
estendido ou \Cake\I18n\FrozenTime
classe com um $_toStringFormat
substituído propriedade, para que formate a data de acordo. 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');
// ...
Isso deve ser autoexplicativo,
time
colunas que estão sendo mapeadas para TimeType
, agora usará App\I18n\FrozenTimeOnly
em vez do padrão Cake\I18n\Time
. DateTimeType::$dateTimeClass
está obsoleto
Para lidar com isso, será necessário um tipo de banco de dados personalizado, o que também é bastante simples.
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);
}
}
Deve-se notar que atualmente isso instanciará uma classe de dados/tempo duas vezes, pois o construtor pai invocará
_setClassName()
também, que é onde uma instância da classe dada será instanciada. src/config/bootstrap.php
use App\Database\Type\TimeOnlyType;
Type::map('time', TimeOnlyType::class);
Então, o que isso fará é substituir o
time
padrão mapeamento de tipo para usar o \App\Database\Type\TimeOnlyType
personalizado classe, que por sua vez usará a classe \App\I18n\TimeOnly
class ao converter valores de banco de dados em objetos PHP, que quando convertidos em uma string, usarão o formato somente de tempo. Veja também
- Cookbook> Time> Definindo a localidade padrão e a string de formato
- Livro de receitas> Banco de dados Acesso e ORM> Noções básicas de banco de dados> Adicionando tipos personalizados