Aktuální čas v MySQL: NOW(), CURDATE(), UTC_TIMESTAMP(), časová pásma a osvědčené postupy

目次

1. Získejte aktuální čas v MySQL (Závěr: Nejkratší SQL Cheat Sheet)

Pokud chcete získat aktuální čas v MySQL, musíte si zapamatovat jen několik SQL funkcí.
Níže je nejkratší odpověď pro vyhledávací klíčové slovo „MySQL get current time“.

1.1 Aktuální datum a čas v MySQL: NOW() / CURRENT_TIMESTAMP

Vrátí aktuální datum + čas (YYYY-MM-DD HH:MM:SS).

SELECT NOW();
SELECT CURRENT_TIMESTAMP;

Příklad výstupu

2025-02-01 15:30:45
  • NOW() a CURRENT_TIMESTAMP obvykle vrací stejný výsledek.
  • Oba vrací aktuální datum a čas.
  • Pokud potřebujete milisekundy, použijte následující.
    SELECT NOW(3);
    

Poznámky (běžné chyby)

  • Závisí na nastavení časové zóny serveru.
  • V prostředí UTC můžete získat UTC místo japonského času.
  • Během provádění dotazu v podstatě vrací stejný čas (fixní v rámci jednoho příkazu).

1.2 Aktuální datum v MySQL: CURDATE()

Vrátí pouze datum (bez času).

SELECT CURDATE();

Příklad výstupu

2025-02-01

Případ použití

  • Dotaz na data z dneška
  • Porovnání dat (např. filtrování pouze záznamů z dneška)

Poznámky

  • Návratová hodnota je typu DATE.
  • Není vhodné, pokud potřebujete zpracování času v průběhu dne.

1.3 Aktuální čas v MySQL: CURTIME()

Vrátí pouze čas.

SELECT CURTIME();

Příklad výstupu

15:30:45

Případ použití

  • Kontrola provozních hodin
  • Větvení logiky podle časového okna

Poznámky

  • Nezahrnuje informace o datu.
  • Nelze ho použít k porovnání se sloupci typu DATE.

1.4 Aktuální UTC čas v MySQL: UTC_TIMESTAMP()

Vrátí čas v UTC (Coordinated Universal Time), bez ohledu na nastavení časové zóny serveru.

SELECT UTC_TIMESTAMP();

Příklad výstupu

2025-02-01 06:30:45

Kdy ho použít

  • Globální služby
  • Návrhy, které ukládají logy konzistentně v UTC

Běžné chyby

  • Míchání s NOW() způsobuje posun času
  • Pokud aplikace předpokládá JST, uvidíte rozdíl 9 hodin

1.5 Aktuální čas v MySQL s milisekundami: NOW(3) / CURRENT_TIMESTAMP(3)

MySQL 5.6 a novější podporuje zlomkové sekundy.

SELECT NOW(3);
SELECT CURRENT_TIMESTAMP(3);

Příklad výstupu

2025-02-01 15:30:45.123

Poznámky k ukládání

Váš sloupec musí také podporovat zlomkové sekundy.

DATETIME(3)
TIMESTAMP(3)

Pokud ho uložíte do sloupce, který to nepodporuje, zlomková část bude zkrácena.

1.6 Rychlý cheat sheet podle účelu

PurposeSQL
Current date and timeSELECT NOW();
Get UTCSELECT UTC_TIMESTAMP();
Date onlySELECT CURDATE();
Time onlySELECT CURTIME();
Get millisecondsSELECT NOW(3);

Shrnutí běžných pastí

  • Čas je posunutý, protože jste neověřili časovou zónu
  • Použití NOW(3) bez sloupce schopného milisekund
  • Míchání UTC a lokálního času
  • Nerozumění rozdílu mezi DATETIME a TIMESTAMP

MySQL DATETIME と TIMESTAMP の違いを示した図。TIMESTAMPはUTC変換され、DATETIMEは変換されない。

Rozdíl mezi MySQL DATETIME a TIMESTAMP (porovnání, zda dochází k konverzi časové zóny)

2. Rozdíly mezi MySQL NOW() a CURRENT_TIMESTAMP

NOW() a CURRENT_TIMESTAMP vypadají podobně, ale nedorozumění, kde je použít a jak se chovají, může snadno způsobit chyby. Zde jsme seřadili rozdíly, správné použití a běžné pasti.

2.1 Který byste měli použít? (Použití v SELECT / Použití jako DEFAULT)

■ Při získávání aktuálního data/času v SELECT

SELECT NOW();
SELECT CURRENT_TIMESTAMP;

Normálně oba vrací stejný výsledek.

  • Jsou ekvivalentní (synonyma)
  • Návratová hodnota je ekvivalentní DATETIME
  • Ovlivněno nastavením časové zóny

Praktický závěr

  • Upřednostněte čitelnost → NOW()
  • Upřednostněte standardní SQL styl → CURRENT_TIMESTAMP

■ Při nastavování výchozí hodnoty sloupce

CREATE TABLE logs (
    id INT AUTO_INCREMENT PRIMARY KEY,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

Klíčový bod zde je:

Pro výchozí hodnotu je běžné použít CURRENT_TIMESTAMP.

Některá prostředí také umožňují NOW(), ale chování se může lišit v závislosti na verzi MySQL a režimu SQL. Bezpečnější volbou je CURRENT_TIMESTAMP.

2.2 Správné použití DEFAULT / ON UPDATE

Pokud chcete automaticky aktualizovat časové razítko „updated at“:

CREATE TABLE logs (
    id INT AUTO_INCREMENT PRIMARY KEY,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
        ON UPDATE CURRENT_TIMESTAMP
);

Chování

  • při INSERT → nastaví aktuální čas pro created_at / updated_at
  • při UPDATE → aktualizuje pouze updated_at

Časté chyby

  • Nesoulad přesnosti zlomkových sekund při použití DATETIME
  • Narazíte na starší omezení MySQL při více sloupcích TIMESTAMP (MySQL 5.6 a starší měly omezení)

2.3 Rozdíly mezi NOW() a SYSDATE() (Důležité)

Snadno přehlédnutý bod je rozdíl oproti SYSDATE().

SELECT NOW(), SYSDATE();

■ Rozdíly v chování

  • NOW() → pevný čas při zahájení dotazu
  • SYSDATE() → vrací čas v okamžiku, kdy je volána

Příklad:

SELECT NOW(), SLEEP(3), NOW();

NOW() vrací stejnou hodnotu.

SELECT SYSDATE(), SLEEP(3), SYSDATE();

SYSDATE() ukazuje rozdíl 3 sekundy.

2.4 Který byste měli použít?

FunctionBehaviorRecommended use
NOW()Fixed within a queryLogging, consistency-focused
SYSDATE()Call-time valuePrecise real-time retrieval

Proč je NOW() často doporučováno v reálných systémech

  • Zachovává konzistenci uvnitř transakce (mechanismus, který zpracovává více SQL příkazů najednou)
  • Bezpečnější v replikacích

2.5 Častá nedorozumění a problémy

❌ „NOW() a CURRENT_TIMESTAMP jsou naprosto stejné, takže o tom nemusíte přemýšlet.“

→ Rozdíly se mohou projevit v výchozích hodnotách nebo chování při aktualizaci, v závislosti na prostředí.

❌ „SYSDATE() je přesnější, takže je vždy lepší.“

→ Může způsobit problémy v replikacích.

❌ Neověřování časové zóny

SHOW VARIABLES LIKE '%time_zone%';

Pokud ji použijete bez kontroly, můžete získat časové posuny.

2.6 Praktické osvědčené postupy

  • SELECT získání → NOW()
  • Výchozí hodnota sloupce → CURRENT_TIMESTAMP
  • Automatická aktualizace → ON UPDATE CURRENT_TIMESTAMP
  • Zaměření na konzistenci → výchozí NOW()
  • Design založený na UTC → TIMESTAMP + ukládat v UTC
  1. Formátování aktuálního času v MySQL (DATE_FORMAT / TIME_FORMAT)
    Po získání aktuálního času v MySQL je velmi běžné změnit formát zobrazení.
    Pro vyhledávací záměr „MySQL current time format“ je nejdůležitější funkcí, kterou je třeba pochopit, DATE_FORMAT().

3.1 Formátování datetime v MySQL: DATE_FORMAT(NOW(), …)

Základní syntaxe:

sql
SELECT DATE_FORMAT(target_datetime, 'format_string');

Příklad: formátování aktuálního času

sql
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i:%s');

Příklad výstupu

2025-02-01 15:30:45

Často používané specifikátory formátu

SpecifikátorVýznamPříklad
%YRok (4 číslice)2025
%mMěsíc (2 číslice)02
%dDen (2 číslice)01
%HHodina (24‑hodinový)15
%hHodina (12‑hodinový)03
%iMinuta30
%sSekunda45
%pAM/PMPM

3.2 Převod na japonský styl nebo 12‑hodinový formát

■ Japonský styl

sql
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %H:%i');

Příklad výstupu:

2025-02-01 15:30

■ 12‑hodinový formát + AM/PM

sql
SELECT DATE_FORMAT(NOW(), '%Y-%m-%d %h:%i:%s %p');

Příklad výstupu:

2025-02-01 03:30:45 PM

3.3 Formátování pouze času v MySQL: TIME_FORMAT()

Formátovací funkce určená výhradně pro data typu TIME.

sql
SELECT TIME_FORMAT(CURTIME(), '%H:%i');

Příklad výstupu:

15:30

Poznámky
TIME_FORMAT() funguje jen pro typ TIME.
– Pro DATETIME použijte DATE_FORMAT().

3.4 Převod řetězce → datetime: STR_TO_DATE()

Pro převod řetězcových dat na typ datetime:

sql
SELECT STR_TO_DATE('2025-02-01 15:30:45', '%Y-%m-%d %H:%i:%s');

Příklad výstupu:

2025-02-01 15:30:45

Časté chyby
– Nesoulad formátu vrací NULL.
– Záměna %m a %c (nulou doplněný vs. nenulový měsíc).

3.5 Důležité body v produkci

Nesrovnávejte po formátování
Špatný příklad:

sql
WHERE DATE_FORMAT(created_at, '%Y-%m-%d') = '2025-02-01';

Toto není doporučeno, protože indexy přestanou fungovat (výkon dotazu klesá).

Doporučeno:

sql
WHERE created_at >= '2025-02-01' AND created_at < '2025-02-02';

Neformátujte příliš na straně DB
Ve webových aplikacích je formátování pro zobrazení obvykle flexibilnější na úrovni aplikace.
Databáze by se měla soustředit na „úložiště a výpočty“.

3.6 Formátování s milisekundami

sql
SELECT DATE_FORMAT(NOW(3), '%Y-%m-%d %H:%i:%s.%f');

%f představuje mikrosekundy (6 číslic).

Poznámka
Pokud sloupec není typu DATETIME(3) nebo podobného, bude desetinná část oříznuta.
K dispozici od MySQL 5.6 a novějších.

3.7 Shrnutí podle účelu formátování

ÚčelFunkce
Změna formátu zobrazeníDATE_FORMAT
Formátování pouze časuTIME_FORMAT
Převod řetězec → datetimeSTR_TO_DATE
Zobrazení milisekund%f
  1. Přidávání a odečítání dat a časů v MySQL (DATE_ADD / DATE_SUB)
    I když můžete získat aktuální čas, nemůžete jej efektivně využít v produkci bez výpočtů dat/časů, jako je „X dní později“ nebo „X hodin zpět“.
    V tomto oddíle vysvětlujeme, jak používat DATE_ADD() a DATE_SUB() s aktuálním časem v MySQL.

4.1 Přidávání datetime v MySQL: DATE_ADD()

Základní syntaxe:

sql
SELECT DATE_ADD(base_datetime, INTERVAL value unit);

Příklad: za 7 dní

sql
SELECT DATE_ADD(NOW(), INTERVAL 7 DAY);

Příklad: za 2 hodiny

sql
SELECT DATE_ADD(NOW(), INTERVAL 2 HOUR);

Často používané jednotky

JednotkaVýznam
SECONDSekundy
MINUTEMinuty
HOURHodiny
DAYDny
MONTHMěsíce
YEARRoky

4.2 Odečítání datetime v MySQL: DATE_SUB()

Základní syntaxe:

sql
SELECT DATE_SUB(base_datetime, INTERVAL value unit);

Příklad: před 30 dny

sql
SELECT DATE_SUB(NOW(), INTERVAL 30 DAY);

Příklad: před 1 hodinou

sql
SELECT DATE_SUB(NOW(), INTERVAL 1 HOUR);

Případy použití
– Kontrola expirace
– Mazání starých logů
– Výběr nedávných dat

4.3 Běžné vzory v produkci

■ Načtení dat za posledních 24 hodin

sql
SELECT * FROM logs WHERE created_at >= DATE_SUB(NOW(), INTERVAL 1 DAY);

■ Nastavení termínu o 7 dní později

sql
INSERT INTO tasks (deadline) VALUES (DATE_ADD(NOW(), INTERVAL 7 DAY));

4.4 Běžné chyby a opatření
❌ Používání funkcí na sloupcích
Špatný příklad:
WHERE DATE(created_at) = CURDATE();
Tím se deaktivují indexy (optimalizace výkonu dotazu).
Doporučeno:
WHERE created_at >= CURDATE() AND created_at < DATE_ADD(CURDATE(), INTERVAL 1 DAY);
❌ Ignorování časových pásem
NOW() je založeno na časovém pásmu serveru
Pokud ukládáte v UTC, použijte UTC_TIMESTAMP() jako základ
Příklad:
SELECT DATE_ADD(UTC_TIMESTAMP(), INTERVAL 1 DAY);
❌ Nástrahy při přidávání měsíců
SELECT DATE_ADD('2025-01-31', INTERVAL 1 MONTH);
→ Kvůli úpravě konce měsíce se datum může změnit.
(Výsledek může být 2025‑02‑28 v závislosti na prostředí.)
Před použitím výpočtů založených na měsících si prostudujte specifikaci.
4.5 Přidávání milisekund
SELECT DATE_ADD(NOW(3), INTERVAL 500 MILLISECOND);
※ MySQL nepodporuje MILLISECOND přímo.
Zadejte v mikrosekundách:
SELECT DATE_ADD(NOW(3), INTERVAL 500000 MICROSECOND);
4.6 Nejlepší postupy
Standardizujte na NOW() nebo UTC_TIMESTAMP() jako základ
Nevkládejte funkce na sloupce ve WHERE klauzuli
Pochopte chování přidávání na základě měsíců
Pokud je vyžadována přesnost, použijte DATETIME(3) nebo vyšší

5. Výpočet rozdílů datum/čas v MySQL (DATEDIFF / TIMESTAMPDIFF)

V produkčních systémech není stačí jen získat aktuální čas. Často potřebujete vypočítat kolik dní uplynulo nebo kolik hodin zbývá.

5.1 Výpočet rozdílů dat: DATEDIFF()

DATEDIFF() vypočítá rozdíl ve dnech mezi dvěma daty.

SELECT DATEDIFF('2025-02-10', '2025-02-01');

Výsledek

9

Klíčové body

  • Vrací rozdíl pouze ve dnech
  • Časová část je ignorována
  • Výsledek může být záporný

Příklad: výpočet dní od vytvoření

SELECT DATEDIFF(NOW(), created_at)
FROM users;

5.2 Výpočet rozdílů podle jednotky: TIMESTAMPDIFF()

TIMESTAMPDIFF() umožňuje specifikovat jednotku.

SELECT TIMESTAMPDIFF(unit, start_datetime, end_datetime);

Příklad: rozdíl v hodinách

SELECT TIMESTAMPDIFF(HOUR, '2025-02-01 10:00:00', '2025-02-01 15:00:00');

Výsledek

5

Běžné jednotky

UnitMeaning
SECONDSeconds
MINUTEMinutes
HOURHours
DAYDays
MONTHMonths
YEARYears

Příklad: výpočet minut od přihlášení

SELECT TIMESTAMPDIFF(MINUTE, login_at, NOW())
FROM users;

5.3 Produkční případy použití

  • Kontroly vypršení relace
  • Kontroly vypršení předplatného
  • Výpočet uplynulého času v logech
  • Logika omezení rychlosti

5.4 Běžné chyby

❌ Použití DATEDIFF, když je vyžadována časová přesnost

DATEDIFF() ignoruje hodiny a minuty.

❌ Obrácení pořadí argumentů

Pořadí je:

TIMESTAMPDIFF(unit, start, end)

Pokud je obráceno, výsledek bude záporný.

❌ Ignorování časových pásem

Pokud kombinujete UTC a lokální čas, rozdíly mohou být nesprávné.

5.5 Nejlepší postupy

  • Používejte TIMESTAMPDIFF(), když záleží na časové přesnosti
  • Používejte DATEDIFF() pro jednoduché výpočty dnů
  • Zajistěte konzistentní používání časových pásem
  • Standardizujte na UTC v distribuovaných systémech

6. Dotazy na časové intervaly pomocí aktuálního času

Jedním z nejčastějších reálných požadavků je získání záznamů v konkrétním časovém rozmezí, například:

  • Dnešní záznamy
  • Posledních 7 dní
  • Posledních 24 hodin
  • Tento měsíc

6.1 Získání dnešních záznamů (přátelské k indexům)

SELECT *
FROM logs
WHERE created_at >= CURDATE()
  AND created_at < DATE_ADD(CURDATE(), INTERVAL 1 DAY);

Proč je to správné

  • Na sloupec není aplikována žádná funkce
  • Indexy zůstávají použitelné
  • Efektivní dotaz na rozsah

6.2 Posledních 7 dní

SELECT *
FROM logs
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 7 DAY);

6.3 Posledních 24 hodin

SELECT *
FROM logs
WHERE created_at >= DATE_SUB(NOW(), INTERVAL 1 DAY);

6.4 Tento měsíc

SELECT *
FROM logs
WHERE created_at >= DATE_FORMAT(NOW(), '%Y-%m-01')
  AND created_at < DATE_ADD(DATE_FORMAT(NOW(), '%Y-%m-01'), INTERVAL 1 MONTH);

V produkčních systémech je často lepší vypočítat hranice na straně aplikace a předat je jako parametry.

6.5 Běžné výkonnostní chyby

❌ Používání funkcí na indexovaných sloupcích

WHERE DATE(created_at) = CURDATE();

To zabraňuje využití indexu a způsobuje úplné skenování tabulky.

❌ Nepřiměřené používání BETWEEN

BETWEEN je inkluzivní a může způsobit problémy s posunem o jednu sekundu.

6.6 Shrnutí osvědčených postupů

  • Vždy používejte podmínky rozsahu pro filtrování dat
  • Vyhněte se používání funkcí na indexovaných sloupcích
  • Upřednostňujte ukládání v UTC v globálních systémech
  • Buďte explicitní ohledně předpokladů o časových pásmech