Problém datetime – unixtime
- Jack06
- Člen | 168
Zdravím, mám následující problém.. Konvertuju čas ( v mysql mám datetime, do jquery kalendáře potřebuji čas ve vteřinách )..
Zde to mám: http://www.hc-srsnisedlcany.cz/..
Vlevo je kalendář.. konverze funguje do 27.3 .. po tomto datu už mi to nefunguje a nenapadá mě proč :-(
přidání nové akce do databáze (formát datetime v DB):
public static function createAction($values) {
$values['dates'] = $values['year'] . "-" . $values['month'] . "-" . $values['day'];
unset($values['year']);
unset($values['month']);
unset($values['day']);
if (!dibi::insert(parent::$pre . 'akce', $values)->execute())
throw new InvalidStateException("Akce nebyla úspěšně přidána. Kontaktujte administrátora.");
}
načtení dat do kalendáře:
public static function getActions( $team ){
return dibi::fetchAll("SELECT dates FROM [".parent::$pre."akce] WHERE ( dates > DATE_SUB(NOW(),INTERVAL 1 MONTH)".($team ? ' && tym_id='.$team : '').")");
}
- html kod:
var actions = new Array (1 {if $dates}{foreach $dates as $date},{=strtotime($date->dates)}000{/foreach}{/if});
a nakonec načtení akce podle konvertovaného času:
public static function getAction( $id ){
return dibi::fetchAll("Select ".parent::$pre."akce.*, ".parent::$pre."tym.name FROM ".parent::$pre."akce INNER join ".parent::$pre."tym on ".parent::$pre."akce.tym_id = ".parent::$pre."tym.id ".($id ? 'where('.parent::$pre.'akce.dates = FROM_UNIXTIME('.substr($id, 0, 10).'))' :'')."");
}
No a z nějakých důvodů nejspíše to poslední od 27.3.2011 dále nechce fungovat. Nevíte, proč a čím by to mohlo být způsobeno, a jak to vyřešit? Děkuji mnohokrát
Editoval Jack06 (25. 3. 2011 22:40)
- Jack06
- Člen | 168
změnil jsem getAction na:
public static function getAction( $id ){
return dibi::fetchAll("Select ".parent::$pre."akce.*, ".parent::$pre."tym.name FROM ".parent::$pre."akce INNER join ".parent::$pre."tym on ".parent::$pre."akce.tym_id = ".parent::$pre."tym.id ".($id ? 'where('.parent::$pre.'akce.dates = "'.strftime('%Y-%m-%d', substr($id, 0, 10)).' 00:00:00")' :'')."");
}
a už to funguje, ale proč mi nechce fungovat tamto nechápu :-( nebo nevím co tam asik ještě narvat navíc aby to šlo…
- kravčo
- Člen | 721
Može to byť tým, že 27.3. sa mení zimný čas na letný. Preto môžu vznikať rôzne problémy pri lokálnej konverzii DATETIME → TIMESTAMP a naopak. Svojho času som o tom čosi písal na dibi fóre. Kto to nezažil asi nepochopí…
Unix timestamp (počet sekúnd od epochy) samozrejme zmena času
zimný/letný nijako neovplyvní (počet sekúnd ktoré uplynuli to nezmení),
to čo je problematické je konverzia dátumu na čas a to najmä pri zmene
letného času na zimný (na jeseň), kedy bude v jeden deň
30.11.2011 dvakrát čas 2.30 ráno. Aplikácia teda nevie jednoznačne
skonvertovať string 2011-11-30T02:30:00
, keďže sú preň platné
dva timestampy (s rozdielom 3600s). Potrebuje dodatočnú informáciu
o časovej zóne – prvých 2.30 bude CEST(+0200), druhých v CET(+0100).
Takisto nedokáže skonvertovať jarný string 27.3.2011T02:30:00
,
pretože takýto čas u nás vôbec nenastane.
- kravčo
- Člen | 721
Moja rada znie: keď ti ide iba o dátum, nastav si pole na DATE a vkladaj tam iba dátum.
Ak inde potrebuješ aj čas ale práve teraz nie, využi MySQL funkciu DATE().
Ak sa nechceš upísať k smrti, niekedy po sebe čítaš kód a chceš nechať vyhniť sql injection, použi radšej prefixy tabuliek z dibi… napríklad takto:
/**
* @credit kravčo
*/
public static function getAction($id)
{
$conds = array();
if ($id) {
// id značí datetime string??? trochu wtf...
$conds[] = array('DATE(:pre:akce.dates) = %s', substr($id, 0, 10));
}
return dibi::fetchAll('
SELECT :pre:akce.*, :pre:tym.name
FROM :pre:akce INNER JOIN :pre:tym ON :pre:akce.tym_id = :pre:tym.id
WHERE %and', $conds, '
');
}
Toto sa už číta o niečo lepšie, nie?