Mysql
 sql >> Datenbank >  >> RDS >> Mysql

CakePHP 3-Zeitspalte bekommt Datum hinzugefügt

Datums-/Uhrzeitwerte werden alle in dieselbe Basisstruktur umgewandelt, das ist ein DateTime oder DateTimeImmutable Objekt, und daher wird reinen Datumswerten natürlich ein Zeitwert hinzugefügt (00:00:00 ) und reine Zeitwerte enthalten ein Datum (das aktuelle Datum).

CakePHP verwendet je nach SQL-Datentyp, also

, bestimmte Unterklassen
  • \Cake\I18n\Time oder \Cake\I18n\FrozenTime für TIME , TIMESTAMP , und DATETIME
  • \Cake\I18n\Date oder \Cake\I18n\FrozenDate für DATE

In früheren Versionen von CakePHP 3 gab es nur \Cake\I18n\Time .

Es wäre schön, wenn es eine separate Klasse für Nur-Zeit-Typen geben würde, die ein richtiges Nur-Zeit-Standardausgabeformat festlegen würden, aber bis so etwas hinzugefügt wird, müssen Sie sich selbst um das Ausgabeformat kümmern .

Formatieren Sie Ihre Ansichten

Wie Sie dies in Ihren Ansichten darstellen, bleibt Ihnen überlassen. Sie können ganz einfach das i18nFormat() verwenden Methode der Time Klasseninstanz

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

oder die Time Helfer, um nur den Zeitteil anzuzeigen

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

Ich schätze, es würde nicht schaden, wenn Bake je nach Art der Spalte ähnlichen Code generieren würde. Vielleicht möchten Sie schlagen Sie das als Verbesserung vor . Wie bereits erwähnt, kann die Verwendung zusätzlicher Klassen (oder vielleicht Optionen) für Nur-Zeit-Spalten auch eine Überlegung wert sein.

Verwenden Sie eine benutzerdefinierte Zeitklasse

Wenn Sie dieses Verhalten überall dort haben wollten, wo die Zeichenfolgendarstellung des Objekts verwendet wird, ohne den Formatierer manuell aufrufen zu müssen, dann könnten Sie einen erweiterten \Cake\I18n\Time verwenden oder \Cake\I18n\FrozenTime Klasse mit einem überschriebenen $_toStringFormat -Eigenschaft, sodass das Datum entsprechend formatiert wird.

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

Das sollte ziemlich selbsterklärend sein, Time Spalten, die TimeType zugeordnet werden , verwendet jetzt App\I18n\FrozenTimeOnly anstelle der Standardeinstellung Cake\I18n\Time .

DateTimeType::$dateTimeClass ist veraltet

Um damit fertig zu werden, wird ein benutzerdefinierter Datenbanktyp benötigt, der auch ziemlich einfach ist.

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

Es sollte beachtet werden, dass dies derzeit eine Daten-/Zeitklasse zweimal instanziiert, da der übergeordnete Konstruktor _setClassName() aufruft auch, wo eine Instanz der angegebenen Klasse instanziiert wird.

src/config/bootstrap.php

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

Dies überschreibt also die Standardeinstellung time Typzuordnung, um den benutzerdefinierten \App\Database\Type\TimeOnlyType zu verwenden Klasse, die wiederum den \App\I18n\TimeOnly verwendet -Klasse beim Konvertieren von Datenbankwerten in PHP-Objekte, die bei der Konvertierung in einen String das Nur-Zeit-Format verwenden.

Siehe auch