Mysql
 sql >> база данни >  >> RDS >> Mysql

Трябва ли MySQL да има часова зона на UTC?

Изглежда, че няма значение коя часова зона е на сървъра, стига да сте настроили времето точно за текущата часова зона, да знаете часовата зона на колоните за дата и час, които съхранявате, и сте наясно с проблемите с лятното часово време.

От друга страна, ако имате контрол върху часовите зони на сървърите, с които работите, можете да настроите всичко на UTC вътрешно и никога да не се притеснявате за часовите зони и DST.

Ето някои бележки, които събрах за това как да работя с часовите зони като форма на измамник за мен и други, които могат да повлияят на това коя часова зона ще избере лицето за своя сървър и как ще съхранява дата и час.

Чайт лист за часова зона на MySQL

Бележки:

  1. Промяната на часовата зона няма да промени съхранената дата и час или клеймо за час , но ще избере различна дата и час от колоните на клеймото за време

  2. Внимание! UTC има високосни секунди, те изглеждат като '2012-06-30 23:59:60' и могат да се добавят на случаен принцип, с 6 месеца предварително предизвестие, поради забавянето на въртенето на Земята

  3. GMT обърква секундите, поради което е измислено UTC.

  4. Внимание! различни регионални часови зони може да генерират една и съща стойност за дата и час поради лятното часово време

  5. Колоната с клеймо за време поддържа само дати от 1970-01-01 00:00:01 до 2038-01-19 03:14:07 UTC, поради ограничение .

  6. Вътрешно колона с времеви отпечатъци на MySQL се съхранява като UTC но когато избирате дата, MySQL автоматично ще я преобразува в часова зона на текущата сесия.

    Когато съхранява дата в клеймо за време, MySQL ще приеме, че датата е в часова зона на текущата сесия и ще я преобразува в UTC за съхранение.

  7. MySQL може да съхранява частични дати в колони за дата и час, те изглеждат като "2013-00-00 04:00:00"

  8. MySQL съхранява "0000-00-00 00:00:00", ако зададете колона за дата и час като NULL, освен ако изрично не зададете колоната да позволява null, когато я създавате.

  9. Прочетете това

За да изберете колона с времеви печат във формат 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`

За да изберете текущата дата и час в UTC:

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.

За да получите текущото времеви печат на UNIX (в секунди):

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

За да получите колоната с времеви печат като UNIX времеви печат

SELECT UNIX_TIMESTAMP(`timestamp`) FROM `table_name`

За да получите UTC колона за дата и час като UNIX времеви печат

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

Вземете текуща часова зона datetime от положително цяло число на UNIX времеви клей

SELECT FROM_UNIXTIME(`unix_timestamp_int`) FROM `table_name`

Вземете UTC дата и час от времеви печат на UNIX

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

Вземете текуща часова зона дата и час от отрицателно цяло число на времеви печат на UNIX

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

Има 3 места, където часовата зона може да бъде зададена в MySQL:

Забележка:Часовата зона може да бъде зададена в 2 формата:

  1. отклонение спрямо UTC:'+00:00', '+10:00' или '-6:00'
  2. като именувана часова зона:„Европа/Хелзинки“, „US/Eastern“ или „MET“

Наименуваните часови зони могат да се използват само ако таблиците с информация за часовите зони в базата данни на mysql са създадени и попълнени.

във файла "my.cnf"

default_time_zone='+00:00'

или

timezone='UTC'

@@global.time_zone променлива

За да видите каква стойност са зададени

SELECT @@global.time_zone;

За да зададете стойност за него, използвайте едно от следните:

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

@@session.time_zone променлива

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/en/time-zone-support.html

Забележка:не можете да направите това, тъй като ще върне NULL:

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

Настройте таблици с часовите зони на mysql

За 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/ )

Вижте пълната история на преходите на DST (лятно часово време) за всяка часова зона

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 timezone ще бъде часовата зона на хост машината, където е инсталиран mysql (освен ако mysql не успее да го определи)

Можете да прочетете повече за работата с DST тук

Кога да не се използва UTC от легендарния Джон Скит:https://codeblog.jonskeet.uk/2019/03/27/storing-utc-is-not-a-silver-bullet/ (Например планирано събитие в бъдеще, което представлява време, а не момент във времето)

свързани въпроси:

Източници:



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Как да изтеглите подправена парола от базата данни и потребителя за удостоверяване?

  2. Как да планирате съхранена процедура в MySQL

  3. Как да сравним две таблици в MySQL

  4. Как да добавите ограничение по подразбиране в MySQL

  5. Как да свържете MySQL база данни с PHP уебсайт