Mysql
 sql >> Base de données >  >> RDS >> Mysql

La colonne de temps de CakePHP 3 obtient la date ajoutée

Les valeurs de date/heure sont toutes converties dans la même structure de base, c'est-à-dire un DateTime ou DateTimeImmutable objet, et donc naturellement les valeurs de date uniquement auront une valeur de temps ajoutée (00:00:00 ), et les valeurs temporelles uniquement sont accompagnées d'une date (la date actuelle).

CakePHP utilisera des sous-classes spécifiques en fonction du type de données SQL, c'est-à-dire

  • \Cake\I18n\Time ou \Cake\I18n\FrozenTime pendant TIME , TIMESTAMP , et DATETIME
  • \Cake\I18n\Date ou \Cake\I18n\FrozenDate pour DATE

Dans les versions antérieures de CakePHP 3, il n'y avait que \Cake\I18n\Time .

Ce serait bien s'il y avait une classe distincte pour les types de temps uniquement, qui aurait un jeu de format de sortie par défaut de temps uniquement, mais jusqu'à ce que quelque chose comme ça soit ajouté, vous devrez prendre soin du format de sortie vous-même .

Mettre en forme vos vues

C'est à vous de décider comment l'afficher dans vos vues. Vous pouvez facilement utiliser le i18nFormat() méthode du Time instance de classe

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

ou le Time helper, pour afficher uniquement la partie horaire

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

Je suppose que cela ne ferait pas de mal si bake générait un code similaire en fonction du type de colonne, vous voudrez peut-être suggérer cela comme amélioration . Comme mentionné, l'utilisation de classes supplémentaires (ou peut-être d'options) pour les colonnes temporelles uniquement peut également valoir la peine d'être envisagée.

Utiliser une classe de temps personnalisée

Si vous vouliez ce comportement partout où la représentation sous forme de chaîne de l'objet est utilisée, sans avoir à invoquer manuellement le formateur, vous pourriez utiliser un \Cake\I18n\Time étendu ou \Cake\I18n\FrozenTime classe avec un $_toStringFormat surchargé propriété, afin qu'elle formate la date en conséquence.

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

Cela devrait à peu près se passer d'explications, time les colonnes qui sont mappées sur TimeType , utilisera désormais App\I18n\FrozenTimeOnly au lieu du Cake\I18n\Time par défaut .

DateTimeType::$dateTimeClass est obsolète

Pour faire face à cela, un type de base de données personnalisé sera nécessaire, ce qui est assez simple aussi.

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

Il convient de noter qu'actuellement, cela instancie une classe data/time deux fois, car le constructeur parent invoquera _setClassName() aussi, où une instance de la classe donnée sera instanciée.

src/config/bootstrap.php

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

Donc, ce que cela va faire, c'est remplacer le time par défaut mappage de type pour utiliser le \App\Database\Type\TimeOnlyType personnalisé classe, qui à son tour utilisera le \App\I18n\TimeOnly lors de la conversion des valeurs de la base de données en objets PHP, qui, une fois convertis en chaîne, utiliseront le format temporel uniquement.

Voir aussi