sql >> Databáze >  >> RDS >> Mysql

Časový sloupec CakePHP 3 má přidáno datum

Hodnoty data/času jsou všechny přetypovány do stejné základní struktury, tedy DateTime nebo DateTimeImmutable objekt, a tak přirozeně hodnoty pouze pro datum budou mít přidanou hodnotu času (00:00:00 ) a hodnoty pouze pro čas jsou opatřeny datem (aktuálním datem).

CakePHP bude používat specifické podtřídy v závislosti na datovém typu SQL, to je

  • \Cake\I18n\Time nebo \Cake\I18n\FrozenTime po dobu TIME , TIMESTAMP a DATETIME
  • \Cake\I18n\Date nebo \Cake\I18n\FrozenDate pro DATE

V dřívějších verzích CakePHP 3 existoval pouze \Cake\I18n\Time .

Bylo by hezké, kdyby existovala samostatná třída pro typy pouze v čase, která by měla nastavený správný výchozí výstupní formát pouze v čase, ale dokud se něco takového nepřidá, budete se muset o výstupní formát postarat sami .

Formátovat v zobrazeních

Je na vás, jak to zobrazíte ve svých pohledech. Můžete snadno použít i18nFormat() metoda Time instance třídy

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

nebo Time pomocníka, aby se zobrazila pouze časová část

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

Hádám, že by nebylo na škodu, kdyby bake vygenerovalo podobný kód podle typu sloupce, možná budete chtít doporučte to jako vylepšení . Jak bylo zmíněno, použití dalších tříd (nebo možná voleb) pro sloupce pouze v čase může být také něco, co stojí za zvážení.

Použít vlastní časovou třídu

Pokud byste chtěli toto chování všude tam, kde se používá řetězcová reprezentace objektu, aniž byste museli ručně spouštět formátovač, pak byste mohli použít rozšířený \Cake\I18n\Time nebo \Cake\I18n\FrozenTime třída s přepsaným $_toStringFormat vlastnost, aby odpovídajícím způsobem naformátoval datum.

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

To by mělo být do značné míry samovysvětlující, time sloupce, které jsou mapovány na TimeType , bude nyní používat App\I18n\FrozenTimeOnly místo výchozího Cake\I18n\Time .

DateTimeType::$dateTimeClass je zastaralé

Abychom se s tím vyrovnali, bude vyžadován vlastní typ databáze, který je také poměrně jednoduchý.

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

Je třeba poznamenat, že v současné době to vytvoří instanci třídy data/čas dvakrát, protože nadřazený konstruktor vyvolá _setClassName() také, což je místo, kde bude instance dané třídy vytvořena.

src/config/bootstrap.php

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

Takže to udělá, že přepíše výchozí time zadejte mapování, abyste použili vlastní \App\Database\Type\TimeOnlyType třída, která zase použije \App\I18n\TimeOnly třídy při převodu databázových hodnot na objekty PHP, které při převodu na řetězec budou používat pouze časový formát.

Viz také



  1. Jak uložit dokončený polygon body leaflet.draw do mysql tabulky

  2. SQL Server CASE výraz

  3. Nelze vytvořit požadovanou službu [org.hibernate.engine.jdbc.env.spi.JdbcEnvironment]

  4. Ustanovení kde filtrovat řádky v MySQL