sql >> Base de Datos >  >> RDS >> Mysql

La columna de tiempo de CakePHP 3 obtiene la fecha agregada

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 para TIME , TIMESTAMP y DATETIME
  • \Cake\I18n\Date o \Cake\I18n\FrozenDate para DATE

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
    ];
}

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'); 
// ...

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.

src/config/bootstrap.php

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