Form Format datumu s databaze

malek8
Člen | 13
+
0
-

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 | 1182
+
+1
-

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
+
0
-

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 | 562
+
+1
-

malek8 napsal(a):

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

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
+
0
-

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
+
0
-

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 | 562
+
0
-

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
+
0
-
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 | 562
+
0
-

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?

nettak2
Člen | 19
+
0
-

@GEpic v db mam prichod,odchod = timestamp a aj vo $form mam ->setType(‚timestamp‘) u oboch.

nettak2
Člen | 19
+
0
-

@GEpic Dakujem velmi pekne s pomocou :) vsetko vyriesene :) odporucam aj ostatnim ak mate problem s niecim napiste mu, rad pomoze :)

majo
Člen | 21
+
0
-

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

toka
Člen | 253
+
0
-

Default value jako 0000-00-00, resp. 0000-00-00 00:00:00 je IMHO fakt blbě. Má tam být NULL, a pak se to nestane.

Martin
Člen | 171
+
0
-

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 | 240
+
0
-

@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)