Los valores de fecha/hora se están convirtiendo en la misma estructura base, es decir, DateTime
o DateTimeImmutable
objeto, por lo que, naturalmente, los valores de solo fecha tendrán un valor de tiempo agregado (00:00:00
), y los valores de solo tiempo vienen con una fecha (la fecha actual).
CakePHP utilizará subclases específicas según el tipo de datos SQL, es decir,
\Cake\I18n\Time
o\Cake\I18n\FrozenTime
paraTIME
,TIMESTAMP
yDATETIME
\Cake\I18n\Date
o\Cake\I18n\FrozenDate
paraDATE
En versiones anteriores de CakePHP 3 solo había \Cake\I18n\Time
.
Sería bueno si hubiera una clase separada para los tipos de solo tiempo, que tendrían un conjunto de formato de salida predeterminado de solo tiempo adecuado, pero hasta que se agregue algo así, tendrá que encargarse del formato de salida usted mismo .
Formato en tus vistas
Depende de usted cómo mostrar esto en sus vistas. Puede usar fácilmente i18nFormat()
método del Time
instancia de clase
$record['start_time']->i18nFormat(
[\IntlDateFormatter::NONE, \IntlDateFormatter::SHORT]
)
o el Time
ayudante, para mostrar solo la parte de tiempo
$this->Time->i18nFormat(
$record['start_time'],
[\IntlDateFormatter::NONE, \IntlDateFormatter::SHORT]
)
Supongo que no estaría de más si Bake generara un código similar según el tipo de columna, es posible que desee sugiero que como una mejora . Como se mencionó, el uso de clases adicionales (o quizás opciones) para columnas de solo tiempo también puede ser algo que valga la pena considerar.
Usar una clase de tiempo personalizada
Si quisiera este comportamiento en todas partes donde se usa la representación de cadena del objeto, sin tener que invocar manualmente el formateador, entonces podría usar un \Cake\I18n\Time
extendido o \Cake\I18n\FrozenTime
clase con un $_toStringFormat
anulado propiedad, para que formatee la fecha en consecuencia.
src/I18n/FrozenTimeOnly.php
namespace App\I18n;
use Cake\I18n\FrozenTime;
class FrozenTimeOnly extends FrozenTime
{
protected static $_toStringFormat = [
\IntlDateFormatter::NONE,
\IntlDateFormatter::SHORT
];
}
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');
// ...
Esto debería explicarse por sí mismo, time
columnas que se asignan a TimeType
, ahora usará App\I18n\FrozenTimeOnly
en lugar del predeterminado Cake\I18n\Time
.
DateTimeType::$dateTimeClass
está en desuso
Para hacer frente a eso, se requerirá un tipo de base de datos personalizado, que también es bastante simple.
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);
}
}
Debe tenerse en cuenta que actualmente esto creará una instancia de una clase de datos/tiempo dos veces, ya que el constructor principal invocará _setClassName()
también, que es donde se instanciará una instancia de la clase dada.
use App\Database\Type\TimeOnlyType;
Type::map('time', TimeOnlyType::class);
Entonces, lo que esto hará es anular el time
predeterminado mapeo de tipos para usar el \App\Database\Type\TimeOnlyType
personalizado class, que a su vez usará el \App\I18n\TimeOnly
class al convertir los valores de la base de datos en objetos PHP, que cuando se conviertan en una cadena, usarán el formato de solo tiempo.
Véase también
- Libro de recetas> Hora> Configuración de la cadena de formato y configuración regional predeterminada
- Recetario> Base de datos Acceso y ORM> Conceptos básicos de la base de datos> Adición de tipos personalizados