Mysql
 sql >> Database >  >> RDS >> Mysql

La colonna del tempo di CakePHP 3 ottiene la data aggiunta

Tutti i valori di data/ora vengono trasmessi alla stessa struttura di base, ovvero un DateTime o DateTimeImmutable oggetto, e quindi naturalmente i valori di sola data avranno un valore temporale aggiunto (00:00:00 ) e i valori di sola ora hanno una data (la data corrente).

CakePHP utilizzerà sottoclassi specifiche a seconda del tipo di dati SQL, ovvero

  • \Cake\I18n\Time o \Cake\I18n\FrozenTime per TIME , TIMESTAMP e DATETIME
  • \Cake\I18n\Date o \Cake\I18n\FrozenDate per DATE

Nelle versioni precedenti di CakePHP 3 c'era solo \Cake\I18n\Time .

Sarebbe bello se ci fosse una classe separata per i tipi solo tempo, che avrebbe un corretto formato di output predefinito solo tempo impostato, ma fino a quando non verrà aggiunto qualcosa del genere, dovrai occuparti del formato di output da solo .

Formatta nelle tue viste

Sta a te come mostrarlo nelle tue visualizzazioni. Puoi facilmente usare i18nFormat() metodo del Time istanza di classe

$record['start_time']->i18nFormat(
    [\IntlDateFormatter::NONE, \IntlDateFormatter::SHORT]
)

o il Time aiutante, per mostrare solo la parte temporale

$this->Time->i18nFormat(
    $record['start_time'],
    [\IntlDateFormatter::NONE, \IntlDateFormatter::SHORT]
)

Immagino che non farebbe male se Bake generasse un codice simile in base al tipo di colonna, potresti voler suggeriscilo come miglioramento . Come accennato, anche l'utilizzo di classi (o forse opzioni) aggiuntive per le colonne di solo tempo può essere qualcosa che vale la pena considerare.

Utilizza una classe temporale personalizzata

Se desideri questo comportamento ovunque in cui viene utilizzata la rappresentazione di stringa dell'oggetto, senza dover richiamare manualmente il formattatore, puoi utilizzare un \Cake\I18n\Time esteso o \Cake\I18n\FrozenTime classe con un $_toStringFormat sovrascritto proprietà, in modo da formattare la data di conseguenza.

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

Questo dovrebbe essere più o meno autoesplicativo, time colonne che vengono mappate a TimeType , ora utilizzerà App\I18n\FrozenTimeOnly invece del valore predefinito Cake\I18n\Time .

DateTimeType::$dateTimeClass è deprecato

Per far fronte a ciò, sarà richiesto un tipo di database personalizzato, che è anche piuttosto semplice.

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

Va notato che attualmente questo istanzia una classe data/time due volte, poiché il costruttore genitore invocherà _setClassName() anche, che è dove verrà istanziata un'istanza della classe data.

src/config/bootstrap.php

use App\Database\Type\TimeOnlyType;
Type::map('time', TimeOnlyType::class);

Quindi ciò che farà è sovrascrivere il time predefinito digitare la mappatura per utilizzare il \App\Database\Type\TimeOnlyType personalizzato classe, che a sua volta utilizzerà \App\I18n\TimeOnly classe durante la conversione dei valori del database in oggetti PHP, che una volta convertiti in una stringa, utilizzeranno il formato solo tempo.

Vedi anche