Udało Ci się uruchomić to zapytanie diagnostyczne na swoim serwerze MySQL.
select @@time_zone, now(), utc_timestamp()
Z Twojego czasu lokalnego i czasu UTC jasno wynika, że ustawienie strefy czasowej serwera to „Kanada/Góra”, a oprogramowanie serwera MySQL nie ma własnego ustawienia strefy czasowej.
Jeśli zabierzesz swoje stoły i przeniesiesz je bez zmian na serwer w pobliskiej strefie czasowej, możesz zawsze zaktualizować oprogramowanie, aby wydać polecenie
set time_zone = 'Canada/Mountain';
zaraz po połączeniu się z oprogramowania. To sprawi, że twoje nowe połączenie MySQL będzie zachowywać się tak, jak twoje obecne w strefie czasowej. Jeśli posiadasz serwer MySQL, możesz ustawić jego domyślną strefę czasową zgodnie ze wskazówkami na tej stronie. http://dev.mysql.com/doc /refman/5.5/en/time-zone-support.html
Oto historia o typach danych czasowych. DATE
, TIME
i DATETIME
wszyscy nie znają strefy czasowej . Po zapisaniu wartości daty/godziny odzyskasz tę samą wartość, nawet jeśli zmienisz ustawienia strefy czasowej.
TIMESTAMP
typ danych jest zależny od strefy czasowej . Te elementy danych są zawsze przechowywane w UTC, znanym również jako Z, czas
, dawniej znany jako Greenwich Mean Time. Po zapisaniu są one zawsze konwertowane na czas UTC, a po pobraniu zawsze są konwertowane z powrotem.
funkcje wbudowane
do uzyskania aktualnej daty i czasu (NOW()
i znajomych) są wrażliwe na strefę czasową . Dadzą wartości w czasie lokalnym. Wyjątkiem są trzy funkcje zaczynające się od UTC_
które dają wartości w czasie UTC.
Wiele wielostrefowych aplikacji MySQL stosuje następującą dyscyplinę operacyjną:
- Poproś każdego użytkownika o preferowaną przez użytkownika strefę czasową lub ustal ją na podstawie innych danych osobowych użytkownika. (Telefony mają te informacje dostarczane z sieci.) Przechowuj je jako przyjazne dla strefy informacji deskryptor strefy czasowej („Ameryka/Nowy Jork”, „Kanada/Góra”, „Europa/Wiedeń” itp.) w imieniu użytkownika.
- Po ustanowieniu sesji MySQL w imieniu użytkownika ustaw strefę czasową użytkownika za pomocą
set time_zone
zapytanie takie jak pokazane powyżej. Powinieneś to zrobić zaraz poconnect
operacja. - Przechowuj daty i godziny dla użytkowników w
TIMESTAMP
typy danych. Zostaną przekonwertowane na czas UTC podczas przechowywania. - Odzyskaj je w razie potrzeby. Zostaną przekonwertowane z powrotem na czas lokalny.
Chodzi o to, że strefa czasowa użytkownika jest częścią jego kontekstu. Działa to dobrze, ponieważ jeśli użytkownik A jest w Vancouver, a użytkownik B w Halifax i z jakiegoś powodu użytkownik B przegląda dane czasowe użytkownika A, zostanie to pokazane użytkownikowi B w czasie atlantyckim mniej więcej automatycznie.
Jest to również dobre, ponieważ w przejrzysty sposób radzi sobie z globalnymi kaprysami zmiany czasu ze światła dziennego na standardowy. Znacznik czasu z zeszłego lata będzie wyświetlany w czasie lokalnym zeszłego lata.
Wielu menedżerów serwerów do użytku globalnego ustawia swój czas serwera systemowego lub domyślną strefę czasową MySQL na UTC. (Twoje nie.)
Innym sposobem poradzenia sobie z tym wszystkim jest sposób, w jaki zacząłeś. Wybierz strefę czasową i przechowuj swoje sygnatury czasowe w odniesieniu do tej strefy czasowej. W takim przypadku najlepiej jest wybrać strefę czasową, która nie zmienia się między czasem letnim a standardowym. Następnie, przechowując czasy w bazie danych, dokonaj jawnej konwersji. Możesz przechowywać czasy od użytkowników w Ottawie, robiąc coś takiego.
INSERT INTO tbl (appt) VALUES ( 'whatever-time' - INTERVAL 120 MINUTE)
i uzyskasz wartości w ten sam sposób. Jest to podatne na błędy, ale możesz sprawić, by zadziałało.
Na koniec możesz samodzielnie przeprowadzać konwersje. Jeśli chcesz wiedzieć, ile minut przesunięcia jest między dowolną strefą czasową a UTC, wypróbuj te dwa zapytania.
set time_zone = 'Canada/Atlantic';
select timestampdiff(minute, utc_timestamp(), now());
O tej porze roku daje to -240, czyli -4:00. Musisz użyć minut, a nie godzin ze względu na przesunięcie strefy czasowej o pół godziny lub kwadrans w niektórych krajach.
Wreszcie uważaj. TIMESTAMP
typy danych nie reprezentują czasów sprzed 1970 r. A na mojej instancji MariaDB 10.0 wydaje się, że idzie do piekła w wiadrze zaraz po 2038-01-19T03:14:07 UTC, kiedy czas przekroczy 32 bity.