sql >> Database >  >> RDS >> Mysql

CakePHP 3 tijdkolom krijgt datum toegevoegd

Datum/tijd-waarden worden allemaal naar dezelfde basisstructuur gecast, dat is een DateTime of DateTimeImmutable object, en dus hebben alleen-datumwaarden een tijdswaarde toegevoegd (00:00:00 ), en alleen-tijdwaarden hebben een datum (de huidige datum).

CakePHP zal specifieke subklassen gebruiken, afhankelijk van het SQL-datatype, dat wil zeggen

  • \Cake\I18n\Time of \Cake\I18n\FrozenTime voor TIME , TIMESTAMP , en DATETIME
  • \Cake\I18n\Date of \Cake\I18n\FrozenDate voor DATE

In eerdere CakePHP 3-versies was er alleen \Cake\I18n\Time .

Het zou leuk zijn als er een aparte klasse zou zijn voor time-only types, die een goede time-only standaard output format zouden hebben, maar totdat zoiets wordt toegevoegd, moet je zelf voor het output format zorgen .

Formaat in uw weergaven

Het is aan u hoe u dit in uw weergaven weergeeft. U kunt eenvoudig de i18nFormat() . gebruiken methode van de Time klasse instantie

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

of de Time helper, om alleen het tijdsdeel te tonen

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

Denk dat het geen kwaad zou als bake vergelijkbare code zou genereren volgens het type kolom, misschien wil je stel dat voor als een verbetering . Zoals vermeld kan het gebruik van extra klassen (of misschien opties) voor tijdgebonden kolommen ook de moeite waard zijn om te overwegen.

Gebruik een aangepaste tijdklasse

Als je dit gedrag overal zou willen hebben waar de tekenreeksrepresentatie van het object wordt gebruikt, zonder dat je de formatter handmatig hoeft aan te roepen, dan zou je gebruik kunnen maken van een uitgebreide \Cake\I18n\Time of \Cake\I18n\FrozenTime klasse met een overschreven $_toStringFormat eigenschap, zodat het de datum dienovereenkomstig opmaakt.

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

Dit zou vrijwel vanzelfsprekend moeten zijn, time kolommen die worden toegewezen aan TimeType , gebruikt nu App\I18n\FrozenTimeOnly in plaats van de standaard Cake\I18n\Time .

DateTimeType::$dateTimeClass is verouderd

Om daarmee om te gaan, is een aangepast databasetype vereist, wat ook vrij eenvoudig is.

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

Houd er rekening mee dat dit momenteel twee keer een data/time-klasse zal instantiëren, omdat de bovenliggende constructor _setClassName() zal aanroepen ook, waar een instantie van de gegeven klasse zal worden geïnstantieerd.

src/config/bootstrap.php

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

Dus wat dit zal doen, is de standaard time overschrijven typetoewijzing om de aangepaste \App\Database\Type\TimeOnlyType . te gebruiken class, die op zijn beurt de \App\I18n\TimeOnly class bij het converteren van databasewaarden naar PHP-objecten, die wanneer ze worden geconverteerd naar een tekenreeks, het alleen-tijdformaat gebruiken.

Zie ook



  1. PostgreSQL - GROUP BY-clausule

  2. Controleer op duplicaten voordat u deze invoegt

  3. MySQL LIKE IN()?

  4. Waarom wordt de auto_increment-id niet één voor één verhoogd, hoe stel je deze in?