Tréninkový deník je velmi jednoduchý. Každý den po celý rok závodníci zapisují, co udělali do předpřipravené tabulky. Celý tréninkový rok je rozdělen do 13 cyklů po 28 dnech.
Přičtením dnů se posunete o hodinu mimo, někdy
V databázi mám tedy uloženo, kdy začíná tréninkový rok, což vychází okolo začátku května. Poté pomocí DATE_ADD přičítám 28 dní, a získám začátky všech cyklů v UNIX_TIMESTAMP. A zde nastal problém, že při přesunu na zimní čas jsem byl o hodinu mimo.
SELECT nazev, zacatek, UNIX_TIMESTAMP(DATE_ADD(zacatek, INTERVAL 363 DAY)) AS konec, UNIX_TIMESTAMP(zacatek) AS cyklus1, UNIX_TIMESTAMP(DATE_ADD(zacatek, INTERVAL 28 DAY)) AS cyklus2, UNIX_TIMESTAMP(DATE_ADD(zacatek, INTERVAL 56 DAY)) AS cyklus3, UNIX_TIMESTAMP(DATE_ADD(zacatek, INTERVAL 84 DAY)) AS cyklus4, ... UNIX_TIMESTAMP(DATE_ADD(zacatek, INTERVAL 336 DAY)) AS cyklus13 FROM sezony WHERE nazev = "2015/2016"
Během 7. cyklu se posunul čas a v tabulce se pak 1 den zopakoval a další cykly byly o den posunuty až do změny zpět na letní čas. Při přesunu zase 1 den v tabulce chyběl.
Bez UNIX_TIMESTAMP
Pokud stejný příkaz provedete, ale bez získání UNIX_TIMESTAMP, vše bude v pořádku. Dny budou sedět.
Přesun času a rozdíl mezi MySQL a PHP
Čas se ve střední Evropě posouvá ze 3:00 na 4:00 nebo ze 3:00 na 2:00. Ve Finsku, kde je o hodinu více se čas se přesouvá ze 4:00 na 5:00 nebo ze 4:00 na 3:00. V roce 2015 se čas přesouval právě 25.10. a pokud uděláme následující výpočty, budou se lišit.
SELECT time_to_sec(timediff('2010-10-25 06:00:00', '2010-10-25 00:00:00' )) / 3600
MySQL vypíše, že rozdíl je 6h, ve skutečnosti je to ale 7h jak vypíše PHP.
var_dump((mktime(6,0,0,10,25,2015) - mktime(0,0,0,10,25,2015))/3600)
Řešení
Jak vyřešit tento problém?
- Vracet místo UNIX_TIMESTAMP datum jako string a parsovat v PHP
- Změnit datum začátku tréninkového roku
První řešení by vyžadovalo také změnu kódu v PHP, protože bych musel získávat datum ze stringu. Protože ale řeším pouze celé dny, nikoli hodiny, můžu změnit datový typ z DATE na DATETIME a začátek roku nastavil na poledne.
V případě posunu na zimní čas se UNIX_TIMESTAMP sice vrátí o hodinu zpět, což ale bude z 12:00 na 11:00, takže jsem stále ve stejném dni.
P.S. Kdyby tréninkový rok začínal v zimním čase, problému si nevšimnu. Timestamp by se posunul o hodinu dopředu, a byl bych stále ve stejném dni.
Měli jste podobný problém, nebo máte jiné řešení? Podělte se s námi v komentářích
K tomuto článku již není možné přidávat další komentáře