Wszystkie wartości daty/godziny są rzutowane na tę samą strukturę bazową, czyli DateTime
lub DateTimeImmutable
obiekt, więc naturalnie wartości zawierające tylko datę będą miały dodaną wartość czasu (00:00:00
), a wartości zawierające tylko czas mają datę (bieżącą datę).
CakePHP użyje określonych podklas w zależności od typu danych SQL, czyli
\Cake\I18n\Time
lub\Cake\I18n\FrozenTime
naTIME
,TIMESTAMP
iDATETIME
\Cake\I18n\Date
lub\Cake\I18n\FrozenDate
dlaDATE
We wcześniejszych wersjach CakePHP 3 był tylko \Cake\I18n\Time
.
Byłoby fajnie, gdyby istniała osobna klasa dla typów tylko czasowych, która miałaby ustawiony prawidłowy domyślny format wyjściowy tylko czasowy, ale dopóki coś takiego nie zostanie dodane, będziesz musiał sam zadbać o format wyjściowy .
Sformatuj w swoich widokach
Od Ciebie zależy, jak pokazać to w swoich poglądach. Możesz łatwo użyć i18nFormat()
metoda Time
instancja klasy
$record['start_time']->i18nFormat(
[\IntlDateFormatter::NONE, \IntlDateFormatter::SHORT]
)
lub Time
pomocnik, aby pokazać tylko część czasu
$this->Time->i18nFormat(
$record['start_time'],
[\IntlDateFormatter::NONE, \IntlDateFormatter::SHORT]
)
Zgadnij, że nie zaszkodzi, jeśli funkcja pieczenia wygeneruje podobny kod w zależności od typu kolumny, możesz chcieć zaproponuj to jako ulepszenie . Jak wspomniano, użycie dodatkowych klas (a może opcji) dla kolumn zawierających tylko czas może być również czymś wartym rozważenia.
Użyj niestandardowej klasy czasu
Jeśli chciałbyś, aby takie zachowanie było wszędzie, gdzie używana jest ciąg znaków reprezentujących obiekt, bez konieczności ręcznego wywoływania programu formatującego, możesz skorzystać z rozszerzonego \Cake\I18n\Time
lub \Cake\I18n\FrozenTime
klasa z nadpisanym $_toStringFormat
właściwość, aby odpowiednio sformatować datę.
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 powinno być oczywiste, time
kolumny, które są mapowane na TimeType
, będzie teraz używać App\I18n\FrozenTimeOnly
zamiast domyślnego Cake\I18n\Time
.
DateTimeType::$dateTimeClass
jest przestarzały
Aby sobie z tym poradzić, wymagany będzie niestandardowy typ bazy danych, co również jest dość proste.
źródło/baza danych/typ/czasOnlyType.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);
}
}
Należy zauważyć, że obecnie spowoduje to dwukrotne utworzenie instancji klasy danych/czasu, ponieważ konstruktor nadrzędny wywoła _setClassName()
również, czyli tam, gdzie zostanie utworzona instancja danej klasy.
src/config/bootstrap.php
use App\Database\Type\TimeOnlyType;
Type::map('time', TimeOnlyType::class);
Więc to, co to zrobi, to nadpisanie domyślnego time
mapowanie typu, aby użyć niestandardowego \App\Database\Type\TimeOnlyType
klasa, która z kolei użyje \App\I18n\TimeOnly
klasa podczas konwertowania wartości bazy danych na obiekty PHP, które po przekonwertowaniu na ciąg znaków będą używać formatu czasu.
Zobacz także
- Książka kucharska> Czas> Ustawianie domyślnych ustawień regionalnych i ciągu formatującego
- Książka kucharska> Baza danych Dostęp i ORM> Podstawy bazy danych> Dodawanie niestandardowych typów