Jak uzyskać aktualną strefę czasową MySQL?

217

Czy ktoś wie, czy istnieje taka funkcja w MySQL?

AKTUALIZACJA

To nie wyświetla żadnych ważnych informacji:

mysql> SELECT @@global.time_zone, @@session.time_zone;
+--------------------+---------------------+
| @@global.time_zone | @@session.time_zone |
+--------------------+---------------------+
| SYSTEM             | SYSTEM              |
+--------------------+---------------------+

A może sam MySQL nie może dokładnie znać time_zoneużywanego, to dobrze, możemy się PHPtu zaangażować , o ile mogę uzyskać ważne informacje, które nie są takie SYSTEM...

użytkownik198729
źródło
3
„możemy zaangażować tutaj PHP” - i czy ta instancja php zawsze będzie na tym samym komputerze co serwer MySQL?
VolkerK
Tak, będą na tej samej maszynie.
user198729
10
Spróbuj, @@system_time_zonejak podano w mojej odpowiedzi poniżej.
Andrew
Ponieważ zadano pytanie, dodano więcej odpowiedzi, może ponownie rozważyć zaakceptowaną odpowiedź?
Timo Huovinen,
1
Mimo że serwer MySQL i PHP znajdują się na tym samym serwerze, mogą pobierać różne strefy czasowe na podstawie swoich ustawień. Czasy te mogą różnić się od tego, co pokazuje Twój system operacyjny i PHP / MySQL.
Bimal Poudel

Odpowiedzi:

227

Z instrukcji ( rozdział 9.6 ):

Bieżące wartości globalnych i specyficznych dla klienta stref czasowych można pobrać w następujący sposób:
mysql> SELECT @@global.time_zone, @@session.time_zone;

Edytuj Powyższe zwraca, SYSTEMjeśli MySQL jest ustawiony jako slave w strefie czasowej systemu, co jest mniej niż pomocne. Ponieważ używasz PHP, jeśli odpowiedź na MySQL brzmi SYSTEM, możesz zapytać system , za pomocą której strefy czasowej używa date_default_timezone_get. (Oczywiście, jak VolkerK wskazał, PHP może być uruchomiony na innym serwerze, ale założenia iść, przy założeniu, że serwer WWW i serwer DB to rozmawiasz są ustawione na [jeśli nie faktycznie w ] ta sama strefa czasowa nie jest ogromny skok.) Ale uwaga: tak jak w przypadku MySQL, możesz ustawić strefę czasową używaną przez PHP (date_default_timezone_set), co oznacza, że ​​może zgłaszać inną wartość niż system operacyjny. Jeśli masz kontrolę nad kodem PHP, powinieneś wiedzieć, czy to robisz i być w porządku.

Ale całe pytanie o strefę czasową, z której korzysta serwer MySQL, może być styczną, ponieważ pytanie serwera o strefę czasową nie mówi absolutnie nic o danych w bazie danych. Czytaj dalej, aby uzyskać szczegółowe informacje:

Dalsza dyskusja :

Jeśli kontrolujesz serwer, możesz oczywiście upewnić się, że strefa czasowa jest znaną ilością. Jeśli nie kontrolujesz serwera, możesz ustawić strefę czasową używaną przez twoje połączenie w następujący sposób:

set time_zone = '+00:00';

To ustawia strefę czasową na GMT, aby wszelkie dalsze operacje (jak now()) wykorzystywały GMT.

Należy jednak pamiętać, że wartości czasu i daty nie są przechowywane z informacjami o strefie czasowej w MySQL:

mysql> create table foo (tstamp datetime) Engine=MyISAM;
Query OK, 0 rows affected (0.06 sec)

mysql> insert into foo (tstamp) values (now());
Query OK, 1 row affected (0.00 sec)

mysql> set time_zone = '+01:00';
Query OK, 0 rows affected (0.00 sec)

mysql> select tstamp from foo;
+---------------------+
| tstamp              |
+---------------------+
| 2010-05-29 08:31:59 |
+---------------------+
1 row in set (0.00 sec)

mysql> set time_zone = '+02:00';
Query OK, 0 rows affected (0.00 sec)

mysql> select tstamp from foo;
+---------------------+
| tstamp              |
+---------------------+
| 2010-05-29 08:31:59 |      <== Note, no change!
+---------------------+
1 row in set (0.00 sec)

mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2010-05-29 10:32:32 |
+---------------------+
1 row in set (0.00 sec)

mysql> set time_zone = '+00:00';
Query OK, 0 rows affected (0.00 sec)

mysql> select now();
+---------------------+
| now()               |
+---------------------+
| 2010-05-29 08:32:38 |      <== Note, it changed!
+---------------------+
1 row in set (0.00 sec)

Więc wiedząc strefę czasową serwera jest ważna tylko pod względem funkcji, które uzyskać czas teraz, takie jak now(), unix_timestamp()itp .; nie mówi nic o strefie czasowej, której używają daty w danych bazy danych. Możesz założyć, że zostały napisane w strefie czasowej serwera, ale założenie to może być błędne. Aby poznać strefę czasową dowolnych dat lub godzin przechowywanych w danych, musisz upewnić się, że są one przechowywane wraz z informacjami o strefie czasowej lub (tak jak ja), aby zawsze znajdowały się w GMT.

Dlaczego założenie, że dane zostały zapisane przy użyciu strefy czasowej serwera, jest wadliwe? Po pierwsze, dane mogły zostać zapisane przy użyciu połączenia, które ustawiło inną strefę czasową. Baza danych mogła zostać przeniesiona z jednego serwera na inny, gdzie serwery znajdowały się w różnych strefach czasowych (wpadłem na to, kiedy odziedziczyłem bazę danych, która przeniosła się z Teksasu do Kalifornii). Ale nawet jeśli dane są zapisywane na serwerze wraz z bieżącą strefą czasową, nadal są niejednoznaczne. W ubiegłym roku, w Stanach Zjednoczonych, czas letni został wyłączony o 2:00 1 listopada. Załóżmy, że mój serwer znajduje się w Kalifornii i korzysta ze strefy czasowej Pacyfiku, a ja mam wartość2009-11-01 01:30:00w bazie danych. Kiedy to było? Czy to 1:30 PDT 1 listopada, czy 1:30 PST 1 listopada (godzina później)? Nie masz absolutnie żadnej możliwości poznania. Morał: zawsze przechowuj daty / godziny w GMT (który nie robi czasu letniego) i konwertuj do żądanej strefy czasowej w razie potrzeby.

TJ Crowder
źródło
5
@ user198729: Nie jest to bez znaczenia , choć nie jest tak pomocne, jak się spodziewałem. Oznacza to: Zapytaj system operacyjny, MySQL jest do tego niewolnikiem.
TJ Crowder
Ciekawe, dlaczego sami musimy ustawić strefę czasową, a następnie ją odzyskać? Ten rodzaj pokonuje cel, prawda? To znaczy, chciałbym zapytać MySQL o strefę czasową, ponieważ nie znam odpowiedzi. Może jestem zdezorientowany i źle zrozumiałem. Czy ktoś może wyjaśnić?
Senthil
1
@Senthil Typ mySQL DATETIMEnie zawiera informacji o strefie czasowej. Dlatego myślę, że zamierzoną podstawową filozofią jest to, aby mySQL był jak najbardziej ślepy na strefę czasową - co oznacza, że ​​użytkownik musi trzymać się jednej strefy czasowej, UTC lub strefy czasowej, w której znajduje się serwer, przechowywać wszystko w tej strefie i rób dowolne konwersje na poziomie aplikacji lub używając CONVERT_TZ()( dev.mysql.com/doc/refman/5.0/en/... ) Przynajmniej tak zawsze rozumiałem, jak to powinno działać, patrząc na rzadkie opcje, które mySQL udostępnia w tym polu.
Pekka
Dzięki, ale to wciąż nie jest rozwiązane, jak mogę uzyskać informacje o TZ dzięki wynikowi now()w PHP?
user198729
Całkowicie zgadzam się z częścią „trzymaj się jednej strefy czasowej podczas zapisywania znacznika czasu”. Ale to-> „… lub strefa czasowa, w której znajduje się serwer…”, jak się tego dowiesz? Powiedzmy, że zapisałeś wszystkie wartości znaczników czasu jako UTC. Ale twój serwer znajduje się w innej strefie czasowej i chcesz pokazać wartości datownika zgodnie z strefą czasową. Więc skąd będziesz wiedzieć, w której strefie czasowej znajduje się twój serwer? Tylko wtedy możesz przekazać pewną wartość do CONVERT_TZ (), aby przekonwertować ją, prawda?
Senthil
196

Poniższe zapytanie zwraca strefę czasową bieżącej sesji.

select timediff(now(),convert_tz(now(),@@session.time_zone,'+00:00'));
JohnZ
źródło
6
To naprawdę właściwa odpowiedź, ponieważ pokazuje, że „SYSTEM” jest rozpoznawany jako strefa czasowa podczas konwersji, dzięki czemu w pełni wystarcza konwersja np. NOW () na dowolną strefę czasową.
nilskp
5
Dzięki, dzięki temu mogłem uzyskać format, który chciałem:select time_format(timediff(now(),convert_tz(now(),@@session.time_zone,'+00:00')),'%H%i');
jordanbtucker
97
SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP)jest prostsze.
Jakub Vrána
3
Lub SELECT TIMESTAMPDIFF(SECOND, NOW(), UTC_TIMESTAMP);uzyskać różnicę w kilka sekund.
philfreo
106

Po prostu SELECT @@system_time_zone;

Zwraca PST(lub cokolwiek, co jest istotne dla twojego systemu).

Jeśli próbujesz określić strefę czasową sesji, możesz użyć tego zapytania:
SELECT IF(@@session.time_zone = 'SYSTEM', @@system_time_zone, @@session.time_zone);

Która zwróci strefę czasową sesji, jeśli różni się od systemowej strefy czasowej.

Andrzej
źródło
6
Jedynym minusem jest to, że jeśli strefa czasowa zmieni się z powodu zmian czasu letniego, nadal będzie zgłaszać tę, która została „zapamiętana” w momencie uruchamiania serwera, patrz błąd mysql 9518
Mark
72

Jak wspomina Jakub Vrána (twórca lub administrator i NotORM ) w komentarzach, aby wybrać aktualnie używane przesunięcie strefy czasowej TIME:

SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP);

Zwróci: 02:00:00jeśli twoja strefa czasowa wynosi +2: 00 dla tej daty

Zrobiłem tutaj cheatheet: Czy MySQL powinien mieć strefę czasową ustawioną na UTC?

Timo Huovinen
źródło
Lub SELECT TIMESTAMPDIFF(SECOND, NOW(), UTC_TIMESTAMP);uzyskać różnicę w kilka sekund.
philfreo
dodatek do @philfreo - zwróć uwagę, że parametry powinny być odwrócone w TIMESTAMPDIFF w porównaniu do TIMEDIFF. Aby wziąć przykład podany w tej odpowiedzi, jeśli TIMEDIFF powróci 02:00:00, odpowiedni TIMESTAMPDIFF zwróci, -2jeśli jednostka to GODZINA, -120jeśli jednostka to MINUTA itp. Aby uzyskać znak odpowiadający strefie czasowej, zamień parametry: SELECT TIMESTAMPDIFF(MINUTE, UTC_TIMESTAMP, NOW())zwróci oczekiwaną 120strefę czasową +2: 00. Powodem do określenia minut jest to, że istnieje kilka stref czasowych z przesunięciem 30 lub 45 minut, patrz en.wikipedia.org/wiki/Time_zone
ToolmakerSteve
1
jest to znacznie lepsza odpowiedź niż odpowiedź zaakceptowana, ponieważ odpowiada ona bezpośrednio na pytanie i daje rozwiązanie zamiast samej teorii.
supersan
10

Aby uzyskać bieżącą strefę czasową mysql, możesz wykonać następujące czynności:

 1. SELECT @@system_time_zone;   //from this you can get the system timezone 
 2. SELECT IF(@@session.time_zone = 'SYSTEM', @@system_time_zone, @@session.time_zone) //This will give you time zone if system timezone is different from global timezone

Teraz, jeśli chcesz zmienić strefę czasową mysql, to:

 1. SET GLOBAL time_zone = '+00:00'   //this will set mysql timezone in UTC
 2. SET @@session.time_zone = "+00:00";  //by this you can chnage the timezone only for your particular session 
Abhinav bhardwaj
źródło
6
SELECT EXTRACT(HOUR FROM (TIMEDIFF(NOW(), UTC_TIMESTAMP))) AS `timezone`

Zwróci strefę czasową jako liczbę całkowitą (np . -6:), obsługując czasy dodatnie lub ujemne (tutaj EXTRACTpojawia się miejsce: HOURsama funkcja zwraca ujemne strefy czasowe jako dodatnie).

Luca Fagioli
źródło
6

Każdemu przyjdzie znaleźć strefę czasową mysql db.

Za pomocą tego zapytania możesz uzyskać aktualną strefę czasową:

mysql> SELECT @@system_time_zone as tz;
+-------+
|  tz   |
+-------+
|  CET  |
+-------+

ttrasn
źródło
4

Komenda wymieniona w opisie zwraca „SYSTEM”, co oznacza, że ​​zajmuje ona strefę czasową serwera. Co nie jest przydatne w naszym zapytaniu.

Poniższe zapytanie pomoże zrozumieć strefę czasową

SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP) as GMT_TIME_DIFF;

Powyższe zapytanie podaje przedział czasu w odniesieniu do uniwersalnego czasu koordynowanego (UTC). Możesz więc łatwo analizować strefę czasową. jeśli strefa czasowa bazy danych to IST, wyjście wyniesie 5:30

UTC_TIMESTAMP

W MySQL UTC_TIMESTAMP zwraca bieżącą datę i godzinę UTC jako wartość w formacie „RRRR-MM-DD GG: MM: SS” lub RRRRMMDDGGMMSS.uuuuuu, w zależności od użycia funkcji, tj. W kontekście łańcuchowym lub liczbowym.

TERAZ()

Funkcja NOW (). MySQL NOW () zwraca wartość bieżącej daty i godziny w formacie „RRRR-MM-DD GG: MM: SS” lub RRRRMMDDGGMMSS.uuuuuu, w zależności od kontekstu (numerycznego lub ciągu) funkcji. CURRENT_TIMESTAMP, CURRENT_TIMESTAMP (), LOCALTIME, LOCALTIME (), LOCALTIMESTAMP, LOCALTIMESTAMP () są synonimami NOW ().

Amitesh
źródło
2

Sprawdź obsługę strefy czasowej serwera MySQL i system_time_zonezmienną systemową. To pomaga?

Pekka
źródło
@ użytkownik, czy możesz podać w pytaniu, jakich informacji dokładnie szukasz (strefa czasowa serwera? Klient?) i jakie narzędzia są do Twojej dyspozycji? Wspominasz o PHP. Czy możesz uzyskać dostęp do wiersza poleceń?
Pekka
5
@ użytkownik również, okazuje się, że jesteś jak kutas odrzucający odpowiedzi od ludzi, którzy starają się być pomocni i nie do końca źle. Nie mam nic przeciwko głosowaniu ani utracie sensu, ale twoje podejście nie zachęca do dalszego szukania rozwiązania.
Pekka
3
@ użytkownik, jak powiedziałem, twoje nastawienie nie motywuje mnie do poszukiwania dalszych odpowiedzi dla ciebie, szczególnie w świetle skąpych informacji, które przekazujesz. Przepraszam.
Pekka
3
@ user198729: Wow, stracić nastawienie. Pekka jest typem faceta, który naprawdę pomaga ludziom. Jeśli sama grzeczność nie wystarcza, by cię zmotywować, spróbuj egoistycznego interesu.
TJ Crowder
2
Tylko moje przemyślenia: nie obraziłbym się, gdyby użytkownik zrobił to samo z moim postem. Chodzi mi o to, że presja na termin lub frustracja dodają ludziom szorstkich krawędzi, ale myślę, że powinniśmy na to pozwolić. Może zbyt wybaczam: |
Senthil
1

Mój framework PHP używa

SET LOCAL time_zone='Whatever'

na po połączeniu, gdzie „Cokolwiek” == date_default_timezone_get ()

Nie moje rozwiązanie, ale zapewnia, że ​​strefa SYSTEMczasowa serwera MySQL jest zawsze taka sama jak PHP

Tak, PHP jest mocno zaangażowane i może na to wpływać

Vladkras
źródło
1

Aby uzyskać bieżący czas zgodnie ze strefą czasową, możesz użyć następujących (w moim przypadku jest to „+5: 30”)

wybierz DATE_FORMAT (convert_tz (now (), @@ session.time_zone, '+ 05:30'), '% Y-% m-% d')

Sanjoy Kanrar
źródło
0

Musisz tylko ponownie uruchomić mysqld po zmianie strefy czasowej Systemu.

Globalna strefa czasowa MySQL zajmuje strefę czasową System. Po zmianie dowolnego takiego atrybutu systemu wystarczy ponownie uruchomić Mysqld.

Storm Young
źródło
po zmianie strefy czasowej w systemie operacyjnym wstawki mysql będą używać nowej strefy czasowej, ale wybiorą teraz (); i wybierz current_timestamp; polecenia nadal będą używać starej strefy czasowej. Aby zsynchronizować wszystkie te usługi, należy ponownie uruchomić usługę mysql.
Manoj Kumar G
0

Wstaw fikcyjny rekord do jednej z baz danych, która ma znacznik czasu Wybierz ten rekord i uzyskaj wartość znacznika czasu. Usuń ten rekord. Pobiera na pewno strefę czasową, której serwer używa do zapisywania danych, i ignoruje strefy czasowe PHP.

pod wiatr
źródło
0

Możesz spróbować:

select sec_to_time(TIME_TO_SEC( curtime()) + 48000);

Tutaj możesz określić różnicę czasu w sekundach

Bala Kayan
źródło
1
nie należy dodawać i odejmować przesunięć. przy świetle dziennym mówiącym, że to jest itp. to pole minowe
eweb
0

Użyj, LPAD(TIME_FORMAT(TIMEDIFF(NOW(), UTC_TIMESTAMP),’%H:%i’),6,’+')aby uzyskać wartość w formacie strefy czasowej MySQL, z którą możesz wygodnie korzystać CONVERT_TZ(). Zwróć uwagę, że otrzymane przesunięcie strefy czasowej jest ważne tylko w momencie, w którym wyrażenie jest oceniane, ponieważ przesunięcie może się zmieniać w czasie, jeśli masz czas letni. Jednak wyrażenie to jest przydatne wraz z NOW()przechowywaniem przesunięcia względem czasu lokalnego, co jednoznacznie określa, co NOW()daje. (W strefach czasowych czasu letniego NOW()przeskakuje o godzinę raz w roku, a zatem ma pewne zduplikowane wartości dla różnych punktów w czasie).

rtc
źródło
0

Może być

select timediff(current_time(),utc_time())

W ten sposób nie uzyskasz bezpośrednio wartości strefy czasowej.

@@global.time_zonenie może być użyte, ponieważ jest zmienną i zwraca wartość 'SYSTEM'.

Jeśli potrzebujesz użyć zapytania w sesji ze zmienioną strefą czasową przy użyciu session SET TIME_ZONE =, to dostaniesz to za pomocą @@session.time_zone. Jeśli zapytasz @@global.time_zone, to dostaniesz 'SYSTEM'.

Jeśli spróbujesz datediff, date_sublub timediffz now()i utc_time(), prawdopodobnie będziesz mieć problemy z konwersją.

Ale rzeczy sugerowane powyżej prawdopodobnie będą działać przynajmniej w przypadku niektórych wersji serwerów. Moja wersja to 5.5.43-37 i jest to hostowane rozwiązanie.

dwaid
źródło
To nie odpowiada jednoznacznie na pytanie. Być może możesz go edytować , aby skupić się na zadanym pytaniu.
Mogsdad
-3

Spróbuj użyć następującego kodu:

//ASP CLASSIC
Set dbdate = Server.CreateObject("ADODB.Recordset")
dbdate.ActiveConnection = MM_connection
dbdate.Source = "SELECT NOW() AS currentserverdate "
dbdate.Open()
currentdate = dbdate.Fields("currentserverdate").Value
response.Write("Server Time is "&currentdate)
dbdate.Close()
Set dbdate = Nothing
Oscar Rojas
źródło