Слідкуйте за питанням /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 внутрішньо, і ніколи не турбуватися про часові пояси та DST.
Ось декілька зауважень, які я зібрав про те, як працювати з часовими поясами як формою шпаргалки для себе та інших, які можуть впливати на те, який часовий пояс людина вибере для свого сервера та як він / вона буде зберігати дату та час.
Примітки:
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)
Примітка. Часовий пояс можна встановити у двох форматах:
Названі часові пояси можна використовувати лише в тому випадку, якщо таблиці даних часового поясу в базі даних 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", і "@@ session.time_zone змінна" можуть повернути "SYSTEM", що означає, що вони використовують часовий пояс, встановлений у "my.cnf".
Щоб імена часових поясів спрацьовували (навіть для часового поясу за замовчуванням), ви повинні налаштувати таблиці даних про часовий пояс, які потрібно заповнити: http://dev.mysql.com/doc/refman/5.1/uk/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
(переконайтеся, що правила домену ваших серверів актуальні 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 година, і обидва не змінюватимуться за DST.
system
Часовий пояс буде часовий пояс на хост - машині , де встановлений MySQL (якщо MySQL не вдається визначити його)
Детальніше про роботу з DST ви можете прочитати тут
пов'язані питання:
Джерела:
table
set modified
= '2016-07-07 08:10 +00: 00'
UNIX_TIMESTAMP(NOW());
також на всі ваші використання того, CONVERT_TZ()
де одним із параметрів є @ @ session.time_zone. Щоб надійно перетворити дату часу UTC в часові позначки UNIX, вам потрібно спочатку встановити часову зону сеансу.
PHP і MySQL мають власні конфігурації часового поясу за замовчуванням. Вам слід синхронізувати час між базою даних та веб-додатком, інакше ви можете запустити деякі проблеми.
Прочитайте цей підручник: Як синхронізувати часові пояси PHP та MySQL
date_default_timezone_set("America/Los_Angeles");
і mysql_query("SET time_zone='" . date('P', time()) . "'");
працювали дуже елегантно!