Jaký zvolit datový sloupec? A jak jednoduše získat formátovaný výstup z unixového časového razítka popřípadě z datumu ve formátu DATETIME?
Teď trochu obecně o jednotlivých datových typech, i když je to
nuda – doporučuji přečíst
.
Ukládání času do mysql databáze lze udělat více způsoby a
v různých formátech.
Může jít o datové sloupce:
TIMESTAMP
Timestamp je „datumočas“ ve formátu „RRRRMMDDHHMMSS“ a rozsahu od 1970–01–01 00:00:00 do 2037–01–01 00:00:00.
Datový typ TIMESTAMP je výhodný pro ukládání datumu vložení řádku (výchozí hodnota je CURRENT_TIMESTAMP), protože při úpravě se aktualizuje i čas v upraveném řádku. (Vlastnost ON UPDATE CURRENT_TIMESTAMP).
V databázi zabírá 4 bajty, při výstupu lze formát datumu a času libovolně měnit (funkce DATE_FORMAT()).
DATE
Uloží datum ve formátu „YYYY-MM-DD“ a s rozsahem „1000–01–01“
až „9999–12–31“.
Zabírá 3 bajty a taktéž lze při výstupu jednoduše formátovat.
TIME
Čas ve formátu „hh:mm:ss“, většinou prezentuje čas dne, ale může
to být i uplynulý čas. Proto má celkem neobvyklý rozsah „-838:59.59“
až „838:59:59“.
Taktéž 3 bajty a jednoduché formátování.
DATETIME
Datum a čas ve formátu „YYYY-MM-DD hh:mm:ss“, rozsah „1000–01–01
00:00:00“ do „9999–12–31 23:59:59“.
Zabírá 8 bajtů.
YEAR
Rok YYYY, rozsah 1901 až 2155 a zabírá 1 bajt.
INT
INT je číselný typ a nikoliv datumový, přesto se v něm dá datum snadno uložit a i jednoduše s tím dá pracovat.
Informace o čase lze uložit i jako číslo, které prezentuje počet uplynulých sekund od začátku unixového času (1.1.1970) – takzvaný UNIX TIMESTAMP. V PHP vrací funkce time() právě počet sekund od začátku unixového času. Jako datový typ pro UNIXové časové razítko doporučuji INT(10). Zabírá 4 bajty.
Ostatní datové sloupce se pro ukládání času nehodí.
Datové typy je dobré znát, usnadní vám to spoustu práce a ušetří i nějaké to místo v databázi. Což sice není v dnešní době příliš podstatné, ale hlavně nedochází ke zbytečným ztrátám výkonu aplikací. (Jen pro představu – uložíte-li si datum v libovolném formátu do datového typu VARCHAR(255), bude zabírat místo 4–8 bajtů celých 256!)
Od teorie se odprostím, ukážu pár příkladů, které se budou hodit.
Vytvoříme si testovací tabulku ve které budeme mít datum uložený ve 3 různých datových formátech, např:
CREATE TABLE `test` (
`id` INT NOT NULL AUTO_INCREMENT PRIMARY KEY ,
`jmeno` VARCHAR( 64 ) NOT NULL ,
`heslo` CHAR( 32 ) NOT NULL ,
`cas` DATETIME NOT NULL ,
`cas_zmeny` TIMESTAMP ON UPDATE CURRENT_TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ,
`cas_unix` INT( 10 ) NOT NULL
);
Vše lze „naklikat“ v phpmyadminovi nebo tento kód okopírujte a vložte v phpmyadminu do „SQL“. Takže tabulku máme, teď se půjdeme podívat, jak zobrazovat, vkládat či upravovat data z PHP skriptů.
Vložení a úprava:
Vezmu jen útržek skriptu s SQL dotazem, jak získat třeba data z formuláře je popsáno v tomto seriálu registrace.
Příklad 1:
<?php
/****** Přidání
* Připojení na databázi, získání proměnných, jejich ošetření atd...
*/
$Vlozeni=mysql_query("
INSERT INTO `test`
(`jmeno`,`heslo`,`cas`, `cas_unix`)
VALUES
('".$Jmeno."', '".$Heslo."', NOW(), ".time().")
") or die ("Chyba v SQL dotazu: " . mysql_error());
// Naschvál jsem vynechal sloupec `cas_zmeny`, vloží se automaticky
// (Výchozí DEFAULT CURRENT_TIMESTAMP)
if($Vlozeni){
echo "Záznam byl uložen";
}
?>
<?php
/****** Úprava
* To samé i při úpravě (spojení na databázi, získání proměnných a jejich ošetření)
*/
$Uprava=mysql_query("
UPDATE `test`
SET
`jmeno`='".$Jmeno."',
`heslo`='".$Heslo."'
WHERE
`id`=".(int)$_POST['id_opravovaneho_zaznamu']."
") or die ("Chyba v SQL dotazu: " . mysql_error());
// Naschvál jsem vynechal sloupec `cas_zmeny`, upraví se automaticky
// (Vlastnost ON UPDATE CURRENT_TIMESTAMP)
if($Uprava){
echo "Záznam byl upraven";
}
?>
Výpis do tabulky je pak jen otázkou chviličky.
Příklad 2:
<?php
/*
* Připojení na databázi...
*/
$Dotaz=mysql_query("
SELECT
`id`, `jmeno`, `cas` , `cas_zmeny`, `cas_unix`
FROM `test`
") or die ("Chyba v SQL dotazu: " . mysql_error());
echo "<table>";
while($zaznam=mysql_fetch_array($Dotaz)){
echo "
<tr>
<td>".$zaznam['id']."</td>
<td>".$zaznam['jmeno']."</td>
<td>".$zaznam['cas']."</td>
<td>".$zaznam['cas_zmeny']."</td>
<td>".$zaznam['cas_unix']."</td>
</tr>
";
}
echo "</table>";
?>
A jak jsem již říkal, formát času můžeš měnit pomocí funkce DATE_FORMAT, její popis najdeme v manuálu – zde. Praktický ukázka přímo v dotazu pro přehlednost.
Příklad 3:
<?php
/*
* Připojení na databázi...
*/
$Dotaz=mysql_query("
SELECT
`id`, `jmeno`, DATE_FORMAT(`cas`, '%Y %m %d') AS `cas`
FROM `test`
") or die ("Chyba v SQL dotazu: " . mysql_error());
// atd...
?>
Z DATETIME můžete získat unixové časové razítko a unixového časového razítka můžeme zístat DATETIME pomocí funkcí UNIX_TIMESTAMP a FROM_UNIXTIME. V databázi tedy nemusíme mít 2× stejný údaj, můžeme si vybrat jednu variantu a tu používat.
Krátký příklad, kde použiju obě tyto funkce, navíc funkce FROM_UNIXTIME umí i rovnou formátovat výstup stejně jako funkce DATE_FORMAT().
Příklad 4:
<?php
/*
* Připojení na databázi...
*/
$Dotaz=mysql_query("
SELECT
`id`, `jmeno`,
UNIX_TIMESTAMP(`cas`) AS `UnixRazitkoZDateTime`,
FROM_UNIXTIME(`cas_unix`) AS `DateTimeZCasovehoRazitka`,
FROM_UNIXTIME(`cas_unix`,'%d.%m.%Y') AS `DateTimeZCasovehoRazitkaFormatovany`
FROM `test`
") or die ("Chyba v SQL dotazu: " . mysql_error());
// Sloupcům přiřadím alias, tak dlouhý je kvůli přehlednosti - pojmenování je na vás.
echo "
<table>
<tr>
<th>ID</th>
<th>Jméno</th>
<th>Unix z datumu</th>
<th>Datum z Unixu</th>
<th>Datum z Unixu formátovaný</th>
</tr>
";
while($zaznam=mysql_fetch_array($Dotaz)){
echo "
<tr>
<td>".$zaznam['id']."</td>
<td>".$zaznam['jmeno']."</td>
<td>".$zaznam['UnixRazitkoZDateTime']."</td>
<td>".$zaznam['DateTimeZCasovehoRazitka']."</td>
<td>".$zaznam['DateTimeZCasovehoRazitkaFormatovany']."</td>
</tr>
";
}
echo "</table>";
?>
MySQL má spoustu možností, umí datumy sčítat, počítat rozdíly mezi
nimi a spoustu dalších věcí, pokud máte zájem – podívejte se do MySQL
manuálu – vaše nová bible 
Po dlouhý odmlce to zase rozjíždíš? :)) nebo tě jen na vánoce chytla
taková můza? Pěkný článek
![]()
(Jen pro představu – uložíte-li si datum v libovolném formátu do datového typu VARCHAR(255), bude zabírat místo 4–8 bajtů celých 256!)
Není pravda. To by bylo v případě CHAR, VARCHAR už podle jména zabírá variabilní prostor. Ale i tak není dobrý nápad ukládat v tom datum.
OK, napsal jsem to blbě. Zabírá X bajtů + 1 bajt pro zaznamenání délky. Čili kdybych chtěl uložit datum „9999–12–31 23:59:59“, zabíralo by 20 bajtů (19+1).
Dík za upozornění. V článku uvedený údaj by platil pro CHAR, kde se zbytek místa v db zaplní mezerami.
cau paradni clanek nechtel bys napsat clanek na nahodny obrazek z galerky? zrovna si s tim nevim rady. dokazal jsem si do promenne dat vsechna id fotek co mam ve tvaru 1,2,3,4,5,6,7,8,9,10 a dat to jako pole $arrayid=array($idfotek);
pak tam mam vyber jednoho toho prvku z pole
$random=array_rand($arrayid);
$id=$arrayid[$random];
echo $id; – a tady mi to vypise vsechny id jako bych dal vypsat idfotek.. nevedel jsem presne jak se zbavit u toho seznamu idecek posledni carky tady mam cely kod. jsem zatim jen zacatecnik samouk.
require „admin/db.php“;
$vsechnaid=mysql_query(„SELECT id FROM fotky ORDER BY id DESC“);
while ($vypisid = mysql_fetch_array($vsechnaid)) {
$seznamid=$seznamid.$vypisid[‚id‘].„,“;
}
$seznamid=$seznamid-„,“;
$posledniquery=mysql_query(„SELECT id FROM fotky ORDER BY id LIMIT 1“);
$poslednivypis = mysql_fetch_array($posledniquery);
$seznamid=$seznamid.„,“.$poslednivypis[‚id‘];
$arrayid=array($seznamid);
$random=array_rand($arrayid);
$id=$arrayid[$random];
echo $id;
exit;
hmmm pokud chces nahodny vyber tak zbytecne to vse srat do PHP jen nahodny vyber zrob SQLkem
SELECT * FROM tabulky ORDER BY RAND() LIMIT 10
napriklad:-)
tj… diky moc vyzkousim. zacatecnik se nezapre. :D
dal me napadl navod na narozeniny.. odpocet proste za 50 dni mas narozeniny (18 let) nebo nejblizsi narozeniny ze vsech registrovanych slavi uzivatel adolfek dne 20.4.1990 (18 let). vim ze by to tam muselo byt odecteni data narozeni roku 1990 od data narozeni roku aktualniho ale prestupne roky a dalsi veci vubec netusim. chtel jsem to udelat na web ale vzdavam to nikde nemuzu nic poradneho najit a samotnemu mi to nejde. jinak web mam rozdelany na www.adolfek.borec.cz/kabr08/
Narozeniny jsou celkem psycho. Hlavně díky konci roku – cosi jsem teď napsal, ale asi by to šlo i jednodušeji.
Zjistí, kdo má do 14 dnů narozeniny (sloupec narozeniny, typ DATE)
/**
Spočítá číslo dne následujících narozenin a porovná,
jestli je mezi číslem dne aktuálního datumu
a číselem dne v určitém zvoleném intervalu.
MySQL 5 only, (c) peCan.cz, 2007
*/
SELECT
*
FROM `uzivatele`
WHERE
IF(
(
TO_DAYS(MAKEDATE( EXTRACT(YEAR FROM CURDATE()),1))
+
(
TIMESTAMPDIFF(
DAY,
MAKEDATE( EXTRACT(YEAR FROM CURDATE()),1),
MAKEDATE( EXTRACT(YEAR FROM CURDATE()),DAYOFYEAR(narozeniny))
)
)
) < TO_DAYS(CURDATE()),
/* Pokud jiz letos mel narozeniny, pricteme 365 dni*/
(
TO_DAYS(MAKEDATE( EXTRACT(YEAR FROM CURDATE()),1))
+
(
TIMESTAMPDIFF(
DAY,
MAKEDATE( EXTRACT(YEAR FROM CURDATE()),1),
MAKEDATE( EXTRACT(YEAR FROM CURDATE()),DAYOFYEAR(narozeniny))
)
)
)+365,
/* Jeste narozeniny nemel */
(
TO_DAYS(MAKEDATE( EXTRACT(YEAR FROM CURDATE()),1))
+
(
TIMESTAMPDIFF(
DAY,
MAKEDATE( EXTRACT(YEAR FROM CURDATE()),1),
MAKEDATE( EXTRACT(YEAR FROM CURDATE()),DAYOFYEAR(narozeniny))
)
)
)
)
BETWEEN
TO_DAYS(CURDATE())
AND
TO_DAYS(DATE_ADD(CURDATE(), INTERVAL 14 DAY))
Pozor, funguje jen na MySQL 5!
diky moc uz to pouzivam!! teda ted na tom pracuju. kdybys nekdy vymyslel kod primo na pocet dni do narozenin bylo by to fajn. nebo ten pocet roku alespon (18let) apod
Počet dní je primitivní – to je patrné i z předchozího příkladu. A věk taky není nic složitého (pokud nechceš zjišťovat, zda již narozeniny letos měl)…
/**
Počet dní od narození, kolitáté LETOS bude mít narozeniny
*/
SELECT
(TO_DAYS(CURDATE()) - TO_DAYS(`narozeniny`) ) AS `PocetDnu`,
(YEAR(CURDATE())-YEAR(`narozeniny`)) AS `Vek`
FROM `test`
diky edit: jo takhle.. ten pocet dni jsem myslel DO narozenin.. a ten vek je takhle bez overeni jestli uz narozky mel docela nepouzitelny. to budou mit vsichni kazdy leden o rok vic. nejlepsi by bylo kdybych si mohl vypsat ze do 30 dnu oslavi narozeniny tito uzivatele a tam bych mel i pocet dni do narozenin a v zavorce kolik oslavi roku. ale to uz je docela slozite. jestli budes mit nekdy cas tak bych za to byl vdecny.
Vypíše počet dní do narozenin a kolik mu bude let.
(
SELECT
*,
(TO_DAYS(MAKEDATE( EXTRACT(YEAR FROM CURDATE()),DAYOFYEAR(narozeniny))) - TO_DAYS(CURDATE()) ) AS `DoNarozenin`,
(YEAR(CURDATE())-YEAR(`narozeniny`)) AS `Vek`
FROM test
WHERE
(
TO_DAYS(MAKEDATE( EXTRACT(YEAR FROM CURDATE()),1))
+
(
TIMESTAMPDIFF(
DAY,
MAKEDATE( EXTRACT(YEAR FROM CURDATE()),1),
MAKEDATE( EXTRACT(YEAR FROM CURDATE()),DAYOFYEAR(narozeniny))
)
)
)
BETWEEN
TO_DAYS(CURDATE())
AND
TO_DAYS(DATE_ADD(CURDATE(), INTERVAL 14 DAY))
)UNION(
SELECT
*,
(TO_DAYS(MAKEDATE( EXTRACT(YEAR FROM CURDATE()) + 1 ,DAYOFYEAR(narozeniny))) - TO_DAYS(CURDATE()) ) AS `DoNarozenin`,
(YEAR(CURDATE())-YEAR(`narozeniny`)) + 1 AS `Vek`
FROM test
WHERE
(
TO_DAYS(MAKEDATE( EXTRACT(YEAR FROM CURDATE()),1))
+
(
TIMESTAMPDIFF(
DAY,
MAKEDATE( EXTRACT(YEAR FROM CURDATE()),1),
MAKEDATE( EXTRACT(YEAR FROM CURDATE()),DAYOFYEAR(narozeniny))
)
)
)+ 365
BETWEEN
TO_DAYS(CURDATE())
AND
TO_DAYS(DATE_ADD(CURDATE(), INTERVAL 14 DAY))
)
prosimte.. zjistil jsem jdnu takovou chybicku a nevim co s ni. kdyz maji dva lide ve stejny den narozeniny tak to vypise nejdriv moje jmeno (20.04.) a potom kamosku (20.04.), a problem je v tom ze u me to napise za 99 dni a u ni za 100 dni.. nevim proc.
halo? help pls.. fakt si nevim rady. vypada to ze to chybuje jen u tech co maj stejny datum narozeni. ale nevim to jiste.
prosimte sry ze porad otravuju, ale kdyz mam tohle:
(„SELECT *, DATE_FORMAT(narozeni, ‚%d.%m.%Y‘) AS
narozeni, DATE_FORMAT(poslprihlaseni, ‚%d.%m.%Y, v
%H:%i‘) AS poslprihlaseni FROM uzivatele ORDER BY
id DESC“)
a potrebuju ty uzivatele seradit abecedne.. jak to udelat? to bude nejak ORDER BY.....? nemuzu to nikde najit.
ORDER BY {sloupec_s_nazvy_uzivatelu}
nebo
ORDER BY {sloupec_s_nazvy_uzivatelu} DESC
jedno bude od A a druhé od Z, musíš vyzkoušet, přesně nevím už na
mě leze senilita ![]()
njn, já jsem ten češtin, přesto se vsadím že moje chybná češtin verze bude vyhledávanější;-)
Promiň, ale hrozně mě bije do očí ten nadpis – DATY a ne DATUMY!!
Horší ale je, jak to formulovat, aby to vyjařovalo datum a ne data
Ještě jednou promiň, na kvalitě článku to neubírá…
Dobrý den pane Petře Graubnere
Jmenuji se Pavel Macalla a chtěl jsem Vás požádat o pár rad.Mam web stránku z názvem http://www.piem.cz/ a momentálně mám, promně nevyřešitelný problěm s dizkuzí najde te ji http://www.piem.cz/diskuze.php. Jak sám vidíte je tam spusty upozornění.má domená php podporuje a i mysql a atd.Urči tě se teď ptáte jestli mám vytvořenou databázi na zapisování dat,mám , ale nejsem si jist zda-li dobře a o co mi jde.
Nyní Vás prosím zda byste se nemohl podívat jaký je problem a případně mi poradit co mám špatně byl bych Vám zavázán.
P.S.Odepsat mi můžete na email Pavel.Macalla@seznam.cz Předem děkuji Přeji přýjemnž den naschledanou.
Ahoj, podle chyb nejsi připojený k databázi.
Bobrý den děkuji za odpověd
Chtěl jsem se zeptat jestli by ste mi stím mohl pomoct šlo by to ? byl bych Vám zavázán
děkuji S pozdravem Pavel Macalla (piem)
nechce sa mi to cele citat mam ulozene time v databaze (sekundy od 1970) a chcem ze komentar pridany pr. 15.11.2008 o 15:16 pls mail dik
**Tlustě**
*Kurzíva*
"Odkaz":http://neco.cz nebo http://neco.cz (i www.neco.cz)
/---code php
php kód
\---