Дополнительный вопрос /server/191331/should-servers-have-their-timezone-set-to-gmt-utc
Должен ли часовой пояс MySQL быть установлен на UTC или он должен быть таким же, как сервер или PHP? (Если это не UTC)
Каковы плюсы и минусы?
Дополнительный вопрос /server/191331/should-servers-have-their-timezone-set-to-gmt-utc
Должен ли часовой пояс MySQL быть установлен на UTC или он должен быть таким же, как сервер или PHP? (Если это не UTC)
Каковы плюсы и минусы?
Ответы:
Кажется, что не имеет значения, какой часовой пояс находится на сервере, если у вас есть время, установленное для текущего часового пояса, вы знаете часовой пояс столбцов даты и времени, которые вы храните, и знаете о проблемах с летним временем.
С другой стороны, если у вас есть контроль над часовыми поясами серверов, с которыми вы работаете, тогда вы можете настроить внутреннее время на UTC и не беспокоиться о часовых поясах и летнем времени.
Вот некоторые заметки, которые я собрал, о том, как работать с часовыми поясами в виде таблицы для меня и других, которые могут повлиять на то, какой часовой пояс выберет человек для своего сервера и как он / она будет хранить дату и время.
Ноты:
GMT сбивает с толку секунды, поэтому был изобретен UTC.
Предупреждение! разные региональные часовые пояса могут давать одно и то же значение даты и времени из-за перехода на летнее время
Внутренне столбец метки времени MySQL хранится как UTC, но при выборе даты MySQL автоматически преобразует его в текущий часовой пояс сеанса.
При сохранении даты в метке времени MySQL предполагает, что дата находится в текущем часовом поясе сеанса, и преобразует ее в UTC для хранения.
независимо от того, в каком часовом поясе находится текущий сеанс MySQL:
SELECT
CONVERT_TZ(`timestamp_field`, @@session.time_zone, '+00:00') AS `utc_datetime`
FROM `table_name`
Вы также можете установить часовой пояс глобального или глобального или текущего сеанса в UTC, а затем выбрать временную метку следующим образом:
SELECT `timestamp_field` FROM `table_name`
SELECT UTC_TIMESTAMP();
SELECT UTC_TIMESTAMP;
SELECT CONVERT_TZ(NOW(), @@session.time_zone, '+00:00');
Пример результата: 2015-03-24 17:02:41
SELECT NOW();
SELECT CURRENT_TIMESTAMP;
SELECT CURRENT_TIMESTAMP();
SELECT @@system_time_zone;
Возвращает "MSK" или "+04: 00" для московского времени, например, есть (или была) ошибка MySQL, когда, если задано числовое смещение, она не будет корректировать переход на летнее время
SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP);
Он вернется 02:00:00, если ваш часовой пояс +2: 00.
SELECT UNIX_TIMESTAMP(NOW());
SELECT UNIX_TIMESTAMP();
SELECT UNIX_TIMESTAMP(`timestamp`) FROM `table_name`
SELECT UNIX_TIMESTAMP(CONVERT_TZ(`utc_datetime`, '+00:00', @@session.time_zone)) FROM `table_name`
SELECT FROM_UNIXTIME(`unix_timestamp_int`) FROM `table_name`
SELECT CONVERT_TZ(FROM_UNIXTIME(`unix_timestamp_int`), @@session.time_zone, '+00:00')
FROM `table_name`
SELECT DATE_ADD('1970-01-01 00:00:00',INTERVAL -957632400 SECOND)
Примечание: часовой пояс может быть установлен в 2 форматах:
Именованные часовые пояса можно использовать только в том случае, если информационные таблицы часовых поясов в базе данных mysql созданы и заполнены.
default_time_zone='+00:00'
или
timezone='UTC'
Чтобы увидеть, какое значение они установлены
SELECT @@global.time_zone;
Чтобы установить для него значение, используйте один из них:
SET GLOBAL time_zone = '+8:00';
SET GLOBAL time_zone = 'Europe/Helsinki';
SET @@global.time_zone='+00:00';
SELECT @@session.time_zone;
Чтобы установить его, используйте любой из них:
SET time_zone = 'Europe/Helsinki';
SET time_zone = "+00:00";
SET @@session.time_zone = "+00:00";
«@@ global.time_zone variable» и «@@ session.time_zone variable» могут возвращать «SYSTEM», что означает, что они используют часовой пояс, установленный в «my.cnf».
Чтобы имена часовых поясов работали (даже для часовых поясов по умолчанию), необходимо настроить таблицы данных о часовых поясах, которые необходимо заполнить: http://dev.mysql.com/doc/refman/5.1/en/time-zone-support. HTML
Примечание: вы не можете сделать это, так как он вернет NULL:
SELECT
CONVERT_TZ(`timestamp_field`, TIMEDIFF(NOW(), UTC_TIMESTAMP), '+00:00') AS `utc_datetime`
FROM `table_name`
Чтобы CONVERT_TZ
работать, вам нужно заполнить таблицы часовых поясов
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` ;
Если они пусты, заполните их, выполнив эту команду
mysql_tzinfo_to_sql /usr/share/zoneinfo | mysql -u root -p mysql
если эта команда выдает ошибку « данные слишком длинные для столбца« аббревиатура »в строке 1 », то это может быть вызвано добавлением символа NULL в конце аббревиатуры часового пояса
исправление заключается в том, чтобы запустить это
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
(убедитесь, что ваши dst правила сервера обновлены zdump -v Europe/Moscow | grep 2011
https://chrisjean.com/updating-daylight-saving-time-on-linux/ )
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
также применяет любые необходимые изменения DST на основе правил в приведенных выше таблицах и даты, которую вы используете.
Примечание.
Согласно документам значение, установленное для time_zone, не изменится, например, если вы установите его как «+01: 00», тогда time_zone будет установлено как смещение от UTC, которое не следует за DST, поэтому он останется неизменным круглый год.
Только названные часовые пояса будут изменять время в летнее время.
Сокращения как CET
всегда будут зимними и CEST
летними, в то время как +01: 00 всегда будут UTC
временем + 1 час, и оба не будут меняться с переходом на летнее время.
system
Часовой пояс будет часовой пояс на хост - машине , где установлен MySQL (если MySQL не удается определить его)
Вы можете прочитать больше о работе с DST здесь
связанные вопросы:
Источники:
table
набор обновлений modified
= '2016-07-07 08:10 +00: 00'
UNIX_TIMESTAMP(NOW());
также на все ваши случаи использования, CONVERT_TZ()
где одним из параметров является `@@ session.time_zone. Для надежного преобразования времени UTC в метки времени UNIX вам, в основном, необходимо сначала установить time_zone сессии.
PHP и MySQL имеют свои собственные настройки часового пояса по умолчанию. Вы должны синхронизировать время между вашей базой данных и веб-приложением, иначе вы можете запустить некоторые проблемы.
Прочтите этот учебник: Как синхронизировать ваши часовые пояса PHP и MySQL
date_default_timezone_set("America/Los_Angeles");
и mysql_query("SET time_zone='" . date('P', time()) . "'");
работал очень элегантно!