Mysql
 sql >> Baza danych >  >> RDS >> Mysql

Czy MySQL powinien mieć swoją strefę czasową ustawioną na UTC?

Wygląda na to, że nie ma znaczenia, jaka strefa czasowa jest na serwerze, o ile masz ustawiony czas odpowiedni dla bieżącej strefy czasowej, znasz strefę czasową przechowywanych kolumn daty i godziny i jesteś świadomy problemów z czasem letnim.

Z drugiej strony, jeśli masz kontrolę nad strefami czasowymi serwerów, z którymi pracujesz, możesz ustawić wszystko wewnętrznie na UTC i nie martwić się o strefy czasowe i czas letni.

Oto kilka notatek, które zebrałem, jak pracować ze strefami czasowymi jako formą ściągawki dla mnie i innych, które mogą mieć wpływ na to, jaką strefę czasową wybierze dana osoba dla swojego serwera i jak będzie przechowywać datę i godzinę.

Ściągawka do strefy czasowej MySQL

Uwagi:

  1. Zmiana strefy czasowej nie zmieni zapisanej daty i godziny ani znacznika czasu , ale wybierze inną datę i godzinę z kolumn datownika

  2. Ostrzeżenie! UTC ma sekundy przestępne, które wyglądają jak „2012-06-30 23:59:60” i mogą być dodawane losowo, z 6 miesięcznym wyprzedzeniem, ze względu na spowolnienie obrotu Ziemi

  3. GMT myli sekundy, dlatego wynaleziono UTC.

  4. Ostrzeżenie! różne regionalne strefy czasowe mogą generować tę samą wartość daty i godziny ze względu na czas letni

  5. Kolumna sygnatury czasowej obsługuje tylko daty od 1970-01-01 od 00:00:01 do 2038-01-19 03:14:07 UTC, ze względu na ograniczenie .

  6. Wewnętrznie kolumna MySQL timestamp jest przechowywany jako UTC ale po wybraniu daty MySQL automatycznie przekonwertuje ją na strefę czasową bieżącej sesji.

    Podczas przechowywania daty w znaczniku czasu, MySQL przyjmie, że data jest w strefie czasowej bieżącej sesji i przekonwertuje ją na czas UTC do przechowywania.

  7. MySQL może przechowywać częściowe daty w kolumnach daty i godziny, które wyglądają jak "2013-00-00 04:00:00"

  8. MySQL przechowuje „0000-00-00 00:00:00”, jeśli ustawisz kolumnę daty/godziny jako NULL, chyba że podczas jej tworzenia ustawisz kolumnę zezwalającą na wartość null.

  9. Przeczytaj to

Aby wybrać kolumnę sygnatury czasowej w formacie UTC

bez względu na strefę czasową, w której znajduje się bieżąca sesja MySQL:

SELECT 
CONVERT_TZ(`timestamp_field`, @@session.time_zone, '+00:00') AS `utc_datetime` 
FROM `table_name`

Możesz także ustawić strefę czasową serwera, globalną lub bieżącą sesji na UTC, a następnie wybrać znacznik czasu w następujący sposób:

SELECT `timestamp_field` FROM `table_name`

Aby wybrać aktualną datę i godzinę w UTC:

SELECT UTC_TIMESTAMP();
SELECT UTC_TIMESTAMP;
SELECT CONVERT_TZ(NOW(), @@session.time_zone, '+00:00');

Przykładowy wynik:2015-03-24 17:02:41

Aby wybrać bieżącą datę i godzinę w strefie czasowej sesji

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

Aby wybrać strefę czasową ustawioną podczas uruchamiania serwera

SELECT @@system_time_zone;

Zwraca „MSK” lub „+04:00” dla czasu moskiewskiego, na przykład występuje (lub był) błąd MySQL, w którym ustawienie przesunięcia liczbowego nie spowoduje zmiany czasu letniego

Aby uzyskać aktualną strefę czasową

SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP);

Zwróci 02:00:00, jeśli twoja strefa czasowa to +2:00.

Aby uzyskać aktualny znacznik czasu UNIX (w sekundach):

SELECT UNIX_TIMESTAMP(NOW());
SELECT UNIX_TIMESTAMP();

Aby uzyskać kolumnę sygnatury czasowej jako sygnaturę czasową UNIX

SELECT UNIX_TIMESTAMP(`timestamp`) FROM `table_name`

Aby uzyskać kolumnę daty i godziny UTC jako znacznik czasu UNIX

SELECT UNIX_TIMESTAMP(CONVERT_TZ(`utc_datetime`, '+00:00', @@session.time_zone)) FROM `table_name`

Pobierz aktualną datę i godzinę strefy czasowej z dodatniej liczby całkowitej UNIX-owej sygnatury czasowej

SELECT FROM_UNIXTIME(`unix_timestamp_int`) FROM `table_name`

Pobierz datę i godzinę UTC ze znacznika czasu UNIX

SELECT CONVERT_TZ(FROM_UNIXTIME(`unix_timestamp_int`), @@session.time_zone, '+00:00') 
FROM `table_name`

Pobierz aktualną datę i godzinę strefy czasowej z ujemnej liczby całkowitej sygnatury czasowej UNIX

SELECT DATE_ADD('1970-01-01 00:00:00',INTERVAL -957632400 SECOND) 

Istnieją 3 miejsca, w których można ustawić strefę czasową w MySQL:

Uwaga:Strefę czasową można ustawić w 2 formatach:

  1. przesunięcie względem czasu UTC:„+00:00”, „+10:00” lub „-6:00”
  2. jako nazwana strefa czasowa:„Europa/Helsinki”, „USA/Wschód” lub „MET”

Nazwane strefy czasowe mogą być używane tylko wtedy, gdy tabele informacji o strefach czasowych w bazie danych mysql zostały utworzone i wypełnione.

w pliku „my.cnf”

default_time_zone='+00:00'

lub

timezone='UTC'

@@global.time_zone zmienna

Aby zobaczyć, na jaką wartość są ustawione

SELECT @@global.time_zone;

Aby ustawić jej wartość, użyj jednej z nich:

SET GLOBAL time_zone = '+8:00';
SET GLOBAL time_zone = 'Europe/Helsinki';
SET @@global.time_zone='+00:00';

Zmienna @@session.time_zone

SELECT @@session.time_zone;

Aby to ustawić, użyj jednego:

SET time_zone = 'Europe/Helsinki';
SET time_zone = "+00:00";
SET @@session.time_zone = "+00:00";

zarówno "@@global.time_zone variable", jak i "@@session.time_zone variable" mogą zwracać "SYSTEM", co oznacza, że ​​używają strefy czasowej ustawionej w "my.cnf".

Aby nazwy stref czasowych działały (nawet dla domyślnej strefy czasowej), musisz skonfigurować tabele informacji o strefie czasowej, które muszą być wypełnione: http://dev.mysql.com/doc /refman/5.1/en/time-zone-support.html

Uwaga:nie możesz tego zrobić, ponieważ zwróci NULL:

SELECT 
CONVERT_TZ(`timestamp_field`, TIMEDIFF(NOW(), UTC_TIMESTAMP), '+00:00') AS `utc_datetime` 
FROM `table_name`

Skonfiguruj tabele stref czasowych mysql

Dla CONVERT_TZ aby pracować, musisz wypełnić tabele stref czasowych

SELECT * FROM mysql.`time_zone` ;
SELECT * FROM mysql.`time_zone_leap_second` ;
SELECT * FROM mysql.`time_zone_name` ;
SELECT * FROM mysql.`time_zone_transition` ;
SELECT * FROM mysql.`time_zone_transition_type` ;

Jeśli są puste, wypełnij je, uruchamiając to polecenie

mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql

jeśli to polecenie wyświetla błąd „dane za długie dla kolumny „skrót” w wierszu 1 ”, może to być spowodowane dodaniem znaku NULL na końcu skrótu strefy czasowej

poprawka polega na uruchomieniu tego

mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql
(if the above gives error "data too long for column 'abbreviation' at row 1")
mysql_tzinfo_to_sql /usr/share/zoneinfo > /tmp/zut.sql

echo "SET SESSION SQL_MODE = '';" > /tmp/mysql_tzinfo_to.sql
cat /tmp/zut.sql >> /tmp/mysql_tzinfo_to.sql

mysql --defaults-file=/etc/mysql/my.cnf --user=verifiedscratch -p mysql < /tmp/mysql_tzinfo_to.sql

(upewnij się, że reguły dst Twoich serwerów są aktualne zdump -v Europe/Moscow | grep 2011 https://chrisjean.com/updating-czas-letni- on-linux/ )

Zobacz pełną historię zmian czasu letniego (Daylight Saving Time) dla każdej strefy czasowej

SELECT 
tzn.Name AS tz_name,
tztt.Abbreviation AS tz_abbr,
tztt.Is_DST AS is_dst,
tztt.`Offset` AS `offset`,
DATE_ADD('1970-01-01 00:00:00',INTERVAL tzt.Transition_time SECOND)  AS transition_date
FROM mysql.`time_zone_transition` tzt
INNER JOIN mysql.`time_zone_transition_type` tztt USING(Time_zone_id, Transition_type_id)
INNER JOIN mysql.`time_zone_name` tzn USING(Time_zone_id)
-- WHERE tzn.Name LIKE 'Europe/Moscow' -- Moscow has weird DST changes
ORDER BY tzt.Transition_time ASC

CONVERT_TZ stosuje również wszelkie niezbędne zmiany czasu letniego na podstawie reguł podanych w powyższych tabelach i używanej daty.

Uwaga:
Zgodnie z dokumentacją , wartość ustawiona dla time_zone nie zmienia się, jeśli ustawisz ją na przykład na „+01:00”, wtedy strefa czasowa zostanie ustawiona jako przesunięcie względem czasu UTC, który nie jest zgodny z czasem letnim, więc pozostanie taka sama przez cały czas przez cały rok.

Tylko nazwane strefy czasowe zmieni czas w czasie letnim.

Skróty, takie jak CET zawsze będzie czas zimowy i CEST będzie czas letni, a +01:00 zawsze będzie UTC czas + 1 godzina i nie zmienią się wraz z czasem letnim.

system strefa czasowa będzie strefą czasową komputera hosta, na którym jest zainstalowany mysql (chyba że mysql tego nie określi)

Więcej informacji o pracy z DST znajdziesz tutaj

Kiedy nie używać UTC legendarnego Jona Skeeta:https://codeblog.jonskeet.uk/2019/03/27/storing-utc-is-not-a-silver-bullet/ (Na przykład zaplanowane wydarzenie w przyszłości, które reprezentuje czas, a nie chwilę w czasie)

powiązane pytania:

Źródła:



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Transpozycja dynamicznych kolumn do wierszy

  2. Potrzebuję mojej strony PHP, aby wyświetlić mój obraz BLOB z bazy danych mysql

  3. Jak porównać dwie tabele w MySQL?

  4. Dynamicznie twórz obiekt PHP na podstawie napisu

  5. Składnia SQL UPDATE – wymieniona przez DBMS