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:
-
Zmiana strefy czasowej nie zmieni zapisanej daty i godziny ani znacznika czasu , ale wybierze inną datę i godzinę z kolumn datownika
-
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
-
GMT myli sekundy, dlatego wynaleziono UTC.
-
Ostrzeżenie! różne regionalne strefy czasowe mogą generować tę samą wartość daty i godziny ze względu na czas letni
-
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 .
-
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.
-
MySQL może przechowywać częściowe daty w kolumnach daty i godziny, które wyglądają jak "2013-00-00 04:00:00"
-
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.
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:
- przesunięcie względem czasu UTC:„+00:00”, „+10:00” lub „-6:00”
- 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:
- Jak ustawić strefę czasową MySQL?
- MySql - SELECT TimeStamp Column w formacie UTC
- Jak to zrobić uzyskać uniksowy znacznik czasu w MySQL z czasu UTC?
- Konwertowanie znacznika czasu serwera MySQL na UTC
- https://dba. stackexchange.com/questions/20217/mysql-set-utc-time-as-default-timestamp
- Jak to zrobić Czy mam aktualną strefę czasową MySQL?
- Pola daty i czasu MySQL i czas letni -- jak mogę odwołać się do "dodatkowej" godziny?
- Konwertowanie wartości ujemnych z FROM_UNIXTIME
Źródła:
- https://bugs.mysql.com/bug.php?id=68861
- http://dev. mysql.com/doc/refman/5.0/en/data-i-czas-funkcje.html
- http://dev.mysql.com/doc/ refman/5.1/pl/datetime.html
- http://en.wikipedia.org/wiki/Coordinated_Universal_Time
- http://shafiqissani.wordpress.com/2010/09/30/how-to-get-the-current-epoch-time-unix-timestamp/
- https://web.ivy.net/~carton/ rant/MySQL-timezones.txt