Form Format datumu s databaze
- malek8
- Člen | 13
Zdravim,
V databaze mám datum, type = date
hodnota: 0000–00–00
default value: 0000–00–00
ale ked si ju dumpnem tak
<?php
Nette\Utils\DateTime #7d6c
date => "-0001-11-30 00:00:00.000000" (27)
timezone_type => 3
timezone => "Europe/Prague" (13)
?>
taktiez v inpute: –0001–11–30 00:00:00
U predvyplnenych hodnot 2016–10–31 je to skoro ok, az na to ze sa tam
zobrazuje čas, teda
2016–10–31 00:00:00
Pokial skusim
->setDefaultValue($this->post->public_from->format(‚y-m-d‘))
crati to –1–11–30
čo s tym?
Díky
nette 2.4 php7
- Pavel Kravčík
- Člen | 1196
Musíš tam mít:
format('Y-m-d')
Viz tabulka (case-sensitive) – http://php.net/…ion.date.php.
Ke kráceným hodnotám změň typ v DB z datetime na date.
Místo 0000 je lépe povolit možnost NULL.
Editoval Pavel Kravčík (4. 10. 2016 12:04)
- malek8
- Člen | 13
Pavel Kravčík napsal(a):
Musíš tam mít:
format('Y-m-d')
Viz tabulka (case-sensitive) – http://php.net/…ion.date.php.
Ke kráceným hodnotám změň typ v DB z datetime na date.
Místo 0000 je lépe povolit možnost NULL.
Diky,
ak dam format(‚Y-m-d‘) tak : –0001–11–30
V db mam date type a skusal som aj NULL aj set default 0000–00–00
pokial tam aj rucne nastavim hodnotu na 0000–00–00 tak mi zobrazi –0001–11–30
Odkud se to bere? –0001–11–30
<?php
$item = $this->model->get($id);
//v db je datum ako: 0000-00-00
dump($item->datum);
?>
vypise:
Nette\Utils\DateTime #5edd
date ⇒ „-0001–11–30 00:00:00.000000“ (27)
timezone_type ⇒ 3
timezone ⇒ „Europe/Prague“ (13)
proc to bere Nette\Utils\DateTime neexistuje Nette\Utils\Date ? :)
?>
Editoval malek8 (4. 10. 2016 13:45)
- GEpic
- Člen | 566
malek8 napsal(a):
Zdravim,
V databaze mám datum, type = date
hodnota: 0000–00–00
default value: 0000–00–00ale ked si ju dumpnem tak
<?php Nette\Utils\DateTime #7d6c date => "-0001-11-30 00:00:00.000000" (27) timezone_type => 3 timezone => "Europe/Prague" (13) ?>
taktiez v inpute: –0001–11–30 00:00:00
U predvyplnenych hodnot 2016–10–31 je to skoro ok, az na to ze sa tam zobrazuje čas, teda
2016–10–31 00:00:00Pokial skusim ->setDefaultValue($this->post->public_from->format(‚y-m-d‘))
crati to –1–11–30
čo s tym?
Díkynette 2.4 php7
Používej typ sloupce TIMESTAMP
Pak používej pro ukládání třeba:
DateTime::createFromFormat('j.n.Y', $datum);
A pro načítání:
$datum = $activeRow->datum->format('j.n.Y');
Nebo formát Y-m-d
, záleží pro koho to děláš. :)
Editoval GEpic (18. 1. 2017 22:11)
- nettak2
- Člen | 19
mam presne ten isty problem s datumom pri UPDATE a ukladani do DB
do DB pri zmeneni datumu mi to ulozi ako : 0000–00–00
a pri zobrazeni danej rezervacie po zmene: –0001–11–30 00:00:00
public function getReservation($id) {
return $this->db->query("SELECT DATE_FORMAT(odchod,'%d.%m.%Y') as odchod, DATE_FORMAT(prichod,'%d.%m.%Y') as prichod, typ_izby, email, meno, priezvisko, odkaz, id_rezervacia FROM rezervacia2 WHERE id_rezervacia=?", $id)->fetch();
}
public function editReservation($values) {
$this->db->query("UPDATE rezervacia2 SET odchod=DATE_FORMAT(?,'%Y-%m-%d'), prichod=DATE_FORMAT(prichod,'%Y-%m-%d'), ? WHERE id_rezervacia = ?",
$values['odchod'], $values, $values['id_rezervacia']);
}
- nettak2
- Člen | 19
Vypisat to vypise do tracy ale vlozi to do DB ako ‚0000–00–00‘ a do
webu ako ‚–0001–11–30 00:00:00‘
`UPDATE rezervacia2
SET odchod=DATE_FORMAT(‚13.01.2017‘,‚%Y-%m-%d‘),
prichod=DATE_FORMAT(‚12.01.2017‘,‚%Y-%m-%d‘),
prichod
=‚12.01.2017‘, odchod
=‚13.01.2017‘,
typ_izby
=‚izbaS‘, email
=‚jj@jj.ss',
meno
='fds‘,
priezvisko
=‚f‘, odkaz
=‚f‘,
id_rezervacia
=‚35‘
WHERE id_rezervacia = ‚35‘`
Prosim o pomoc, DAKUJEM
- GEpic
- Člen | 566
Nepoužívej DATE_FORMAT() funkci v databázi, není třeba znova vymýšlet kolo, když už ho někdo vymyslel (a hodně dobře!), připrav si ty hodnoty v PHP a přečti si můj příspěvek vejš, mělo by ti to pomoct.
PS:
Používáš Nette\Database / ActiveRow? Pak nemusíš psát ty ošklivé query
ale stačí bohatě:
public function getReservation($id)
{
// s tím že ActiveRow ti automaticky vrátí DateTime tam,
// kde jsi měl sloupec TIMESTAMP a můžeš s tím tak rovnou pracovat
return $this->db->table('rezervacia2')->get($id);
}
public function editReservation($values, $dateFormat = 'j.n.Y')
{
/* @var ActiveRow $zaznam */
$zaznam = $this->db->table('rezervacia2')->get($values['id_rezervacia']);
// Zde si nastav format, ktery mas ve formulari
$values['prichod'] = DateTime::createFromFormat($dateFormat, $values['prichod']);
$values['odchod'] = DateTime::createFromFormat($dateFormat, $values['odchod']);
// A pak uz jen ulozis :)
$zaznam->update($values);
}
PS2:
Pomíchal sis '%d.%m.%Y'
a '%Y-%m-%d'
, ale můj
příklad má výhodu v tom, že můžeš přijímat kdykoliv jakýkoliv
formát (a správně ho samozřejmě detekovat) a zpětně si ho můžeš taky
naformátovat jak potřebuješ.
Editoval GEpic (18. 1. 2017 22:23)
- nettak2
- Člen | 19
public function getReservation($id) {
return $this->db->query("SELECT * FROM rezervacia2 WHERE id_rezervacia=?", $id)->fetch();
}
@GEpic Nepoužívám Nette\Database / ActiveRow pretoze mi to spravilo bordel tak som to nechal a len zmenil…ale stale mi to robi to iste neviem teda kde robim chybu
public function editReservation($values, $dateFormat = 'j.n.Y') {
/* @var ActiveRow $zaznam */
$zaznam = $this->db->query("SELECT * FROM rezervacia2 WHERE id_rezervacia=?", $values['id_rezervacia'])->fetch();
// Zde si nastav format, ktery mas ve formulari
$values['prichod'] = DateTime::createFromFormat($dateFormat, $values['prichod'])->format('d.m.Y');
$values['odchod'] = DateTime::createFromFormat($dateFormat, $values['odchod'])->format('d.m.Y');
// A pak uz jen ulozis :)
$this->db->query("UPDATE rezervacia2 SET ? WHERE id_rezervacia = ?",
$values, $values['id_rezervacia']);
}
vopred DIKY :)
- GEpic
- Člen | 566
nettak2 napsal(a):
public function getReservation($id) { return $this->db->query("SELECT * FROM rezervacia2 WHERE id_rezervacia=?", $id)->fetch(); }
@GEpic Nepoužívám Nette\Database / ActiveRow pretoze mi to spravilo bordel tak som to nechal a len zmenil…ale stale mi to robi to iste neviem teda kde robim chybu
public function editReservation($values, $dateFormat = 'j.n.Y') { /* @var ActiveRow $zaznam */ $zaznam = $this->db->query("SELECT * FROM rezervacia2 WHERE id_rezervacia=?", $values['id_rezervacia'])->fetch(); // Zde si nastav format, ktery mas ve formulari $values['prichod'] = DateTime::createFromFormat($dateFormat, $values['prichod'])->format('d.m.Y'); $values['odchod'] = DateTime::createFromFormat($dateFormat, $values['odchod'])->format('d.m.Y'); // A pak uz jen ulozis :) $this->db->query("UPDATE rezervacia2 SET ? WHERE id_rezervacia = ?", $values, $values['id_rezervacia']); }
vopred DIKY :)
A jaký typ mají ty sloupce s datumem?
- majo
- Člen | 21
robi to preto, lebo 0000–00–00 nie je validny datum (00 nemoze byt mesiac ani den) a preto to cele posunie o jednu „hodnotu“ nizsie, teda 11 mesiac a v nom 30 den.. rok potom posunie dole, cim vznikne tento „problem“..
potrebujem mat stlpec typu DATETIME a tiez si lamem hlavu ako to elegantne vyriesit.. ideal keby sa nevracalo ziadne datetime :( , ale raw hodnota z db
- Martin
- Člen | 171
GEpic napsal(a):
…
public function getReservation($id) { // s tím že ActiveRow ti automaticky vrátí DateTime tam, // kde jsi měl sloupec TIMESTAMP a můžeš s tím tak rovnou pracovat return $this->db->table('rezervacia2')->get($id); } public function editReservation($values, $dateFormat = 'j.n.Y') { /* @var ActiveRow $zaznam */ $zaznam = $this->db->table('rezervacia2')->get($values['id_rezervacia']); // Zde si nastav format, ktery mas ve formulari $values['prichod'] = DateTime::createFromFormat($dateFormat, $values['prichod']); $values['odchod'] = DateTime::createFromFormat($dateFormat, $values['odchod']); // A pak uz jen ulozis :) $zaznam->update($values); }
…
Ahoj.
Řešil jsem problém se setType(‚date‘) u větších formulářů a nastavovat v metodě edit pro každý date input znovu formát mi nepřišlo úplně dobré, protože pro stejný prvek musím něco řešit na dvou místech.
Zatím jsem to vyřešil přetížením metody setValues pro Nette\Forms\Container, ale také se mi to úplně nelíbí:
<?php
public function setValues($values, $erase = false)
{
if ($values instanceof \Traversable) {
$values = iterator_to_array($values);
} elseif (!is_array($values)) {
throw new Nette\InvalidArgumentException(sprintf('First parameter must be an array, %s given.', gettype($values)));
}
foreach ($this->getComponents() as $name => $control) {
if ($control instanceof Nette\Forms\IControl) {
if (array_key_exists($name, $values)) {
if (isset($control->control->attrs) && $control->control->attrs['type'] == 'date' && $values[$name] instanceof \Nette\Utils\DateTime)
{
$control->setValue((new \Nette\Utils\DateTime($values[$name]))->format('Y-m-d'));
}
else
{
$control->setValue($values[$name]);
}
} elseif ($erase) {
$control->setValue(null);
}
} elseif ($control instanceof self) {
if (array_key_exists($name, $values)) {
$control->setValues($values[$name], $erase);
} elseif ($erase) {
$control->setValues([], $erase);
}
}
}
return $this;
}
?>
Podobnou funkci mohu zavolat i v edit metodě místo setDefaults() s kontrolou, odkud je volána, ale to by neřešilo, že to potřebuju pro více formulářů.
Co si o tom myslíte? Není lepší vytvořit vlastní formulářový prvek, který bude na vstupu filtrovat datum? To mi také nepřijde ideální, když už Nette v sobě podporu HTML5 date inputu má, jen je nekompatibilní jeho vstupní formát s \Nette\Utils\DateTime pro čtení sloupců typu DATE z databáze.
______________________
Doplnění: Asi by šlo i přetížit metodu setValue() u textBase, ale nejsem si jistý, jestli by to neovlivnilo chování formulářů. Neexistuje v Nette u prvků formulářů něco jako metody setInputFilter() a setOutputFilter()? Pokud ne, zdrojové kódy formulářů mi připadají jednoduše pochopitelné oproti jiným částem a v případě zájmu to mohu připravit. Ale dokončit by určitě musel někdo, kdo má s Nette větší zkušenosti.
Editoval Martin (25. 1. 2018 22:20)
- steelbull
- Člen | 241
@Martin Čo mám robiť? Mám ten istý problém. Vracia mi to –0001–11–30 00:00:00 pri Null hodnote v DB. Mám celú aplikáciu prekopať a zmeniť na TimeStamp? Alebo ste prišli na nejaké elegantnejšie riešenie? Keby mi to vrátilo prázdny string alebo null, bol by som spokojný.
Diq.
Martin napsal(a):
GEpic napsal(a):
…
public function getReservation($id) { // s tím že ActiveRow ti automaticky vrátí DateTime tam, // kde jsi měl sloupec TIMESTAMP a můžeš s tím tak rovnou pracovat return $this->db->table('rezervacia2')->get($id); } public function editReservation($values, $dateFormat = 'j.n.Y') { /* @var ActiveRow $zaznam */ $zaznam = $this->db->table('rezervacia2')->get($values['id_rezervacia']); // Zde si nastav format, ktery mas ve formulari $values['prichod'] = DateTime::createFromFormat($dateFormat, $values['prichod']); $values['odchod'] = DateTime::createFromFormat($dateFormat, $values['odchod']); // A pak uz jen ulozis :) $zaznam->update($values); }
…
Ahoj.
Řešil jsem problém se setType(‚date‘) u větších formulářů a nastavovat v metodě edit pro každý date input znovu formát mi nepřišlo úplně dobré, protože pro stejný prvek musím něco řešit na dvou místech.
Zatím jsem to vyřešil přetížením metody setValues pro Nette\Forms\Container, ale také se mi to úplně nelíbí:
<?php public function setValues($values, $erase = false) { if ($values instanceof \Traversable) { $values = iterator_to_array($values); } elseif (!is_array($values)) { throw new Nette\InvalidArgumentException(sprintf('First parameter must be an array, %s given.', gettype($values))); } foreach ($this->getComponents() as $name => $control) { if ($control instanceof Nette\Forms\IControl) { if (array_key_exists($name, $values)) { if (isset($control->control->attrs) && $control->control->attrs['type'] == 'date' && $values[$name] instanceof \Nette\Utils\DateTime) { $control->setValue((new \Nette\Utils\DateTime($values[$name]))->format('Y-m-d')); } else { $control->setValue($values[$name]); } } elseif ($erase) { $control->setValue(null); } } elseif ($control instanceof self) { if (array_key_exists($name, $values)) { $control->setValues($values[$name], $erase); } elseif ($erase) { $control->setValues([], $erase); } } } return $this; } ?>
Podobnou funkci mohu zavolat i v edit metodě místo setDefaults() s kontrolou, odkud je volána, ale to by neřešilo, že to potřebuju pro více formulářů.
Co si o tom myslíte? Není lepší vytvořit vlastní formulářový prvek, který bude na vstupu filtrovat datum? To mi také nepřijde ideální, když už Nette v sobě podporu HTML5 date inputu má, jen je nekompatibilní jeho vstupní formát s \Nette\Utils\DateTime pro čtení sloupců typu DATE z databáze.
______________________
Doplnění: Asi by šlo i přetížit metodu setValue() u textBase, ale nejsem si jistý, jestli by to neovlivnilo chování formulářů. Neexistuje v Nette u prvků formulářů něco jako metody setInputFilter() a setOutputFilter()? Pokud ne, zdrojové kódy formulářů mi připadají jednoduše pochopitelné oproti jiným částem a v případě zájmu to mohu připravit. Ale dokončit by určitě musel někdo, kdo má s Nette větší zkušenosti.
Editoval steelbull (25. 2. 2018 18:54)