Tento dotaz časové diagnostiky jste spustili na svém serveru MySQL.
select @@time_zone, now(), utc_timestamp()
Z vašeho místního času a času UTC je zřejmé, že nastavení systémového časového pásma vašeho serverového počítače je „Kanada/Mountain“ a serverový software MySQL nemá vlastní nastavení časového pásma.
Pokud si vyzvednete stoly a přesunete je beze změny na server v nějakém blízkém časovém pásmu, můžete svůj software vždy aktualizovat a vydat příkaz
set time_zone = 'Canada/Mountain';
ihned po připojení z vašeho softwaru. Díky tomu se bude vaše nové připojení MySQL chovat stejně jako vaše stávající, pokud jde o časové pásmo. Pokud vlastníte server MySQL, můžete nastavit jeho výchozí časové pásmo podle pokynů na této stránce. http://dev.mysql.com/doc /refman/5.5/en/time-zone-support.html
Nyní je zde příběh o typech časových dat. DATE
, TIME
a DATETIME
všechny neznají časové pásmo . Jakmile uložíte hodnotu data/času, získáte ji zpět se stejnou hodnotou, i když změníte nastavení časového pásma.
TIMESTAMP
datový typ je citlivý na časové pásmo . Tyto datové položky jsou vždy uloženy v UTC, známém také jako Z, čas
, dříve známý jako Greenwichský čas. Po uložení jsou vždy převedeny na UTC a po načtení vždy zpět.
vestavěné funkce
pro získání aktuálního data a času (NOW()
a přátelé) jsou citlivé na časové pásmo . Budou poskytovat hodnoty v místním čase. Výjimkou jsou tři funkce začínající UTC_
které poskytují hodnoty v čase UTC.
Mnoho aplikací MySQL pro více časových pásem používá následující provozní disciplínu:
- Požádejte každého uživatele o časové pásmo, které uživatel preferuje, nebo jej zjistěte z jiných osobních údajů o uživateli. (Telefony mají tyto informace zpřístupněny ze sítě.) Uložte to jako přívětivé k zónám deskriptor časového pásma ('Amerika/New_York', 'Kanada/Mountain', 'Evropa/Vídeň' atd.) jménem uživatele.
- Po vytvoření relace MySQL jménem uživatele nastavte časové pásmo uživatele pomocí
set time_zone
dotaz podobný tomu uvedenému výše. Měli byste to udělat hned poconnect
operace. - Ukládejte data a časy pro uživatele do
TIMESTAMP
typy dat. Jakmile budou uloženy, budou převedeny na UTC. - V případě potřeby je načtěte. Budou převedeny zpět na místní čas.
Myšlenka je taková, že časové pásmo vašeho uživatele je součástí jeho kontextu. To funguje dobře, protože pokud je uživatel A ve Vancouveru a uživatel B v Halifaxu a z nějakého důvodu uživatel B prohlíží časové údaje uživatele A, zobrazí se B v atlantickém čase víceméně automaticky.
Je to také dobré, protože se transparentně vypořádává s globálními rozmary změny denního světla na standardní čas. Časové razítko z loňského léta se zobrazí v místním čase loňského léta.
Mnoho správců serverů pro globální použití nastavuje čas svého systémového serveru nebo výchozí časové pásmo MySQL na UTC. (Vaše ne.)
Dalším způsobem, jak to všechno zvládnout, je způsob, jakým jste začali. Vyberte časové pásmo a uložte si časová razítka s ohledem na toto časové pásmo. Nejlepší je vybrat časové pásmo, které v takovém případě nestřídá denní a standardní čas. Poté při ukládání časů do databáze převeďte explicitně. Něco takového byste uložili časy od uživatelů v Ottawě.
INSERT INTO tbl (appt) VALUES ( 'whatever-time' - INTERVAL 120 MINUTE)
a hodnoty dostanete stejným způsobem. Toto je náchylné k chybám, ale můžete to zajistit.
Nakonec můžete své konverze provádět sami. Pokud chcete vědět, kolik minut je posun mezi libovolným časovým pásmem a UTC, zkuste tyto dva dotazy.
set time_zone = 'Canada/Atlantic';
select timestampdiff(minute, utc_timestamp(), now());
V tuto roční dobu to vrací -240, což je -4:00. Kvůli půlhodinovým nebo čtvrthodinovým posunům časových pásem v některých zemích musíte používat minuty místo hodin.
Konečně pozor. TIMESTAMP
datové typy nepředstavují časy před rokem 1970. A na mé instanci MariaDB 10.0 to vypadá, že jde do pekla hned po 2038-01-19T03:14:07 UTC, kdy se čas převalí z 32 bitů.