Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

MySQL có nên đặt múi giờ thành UTC không?

Có vẻ như múi giờ trên máy chủ không quan trọng miễn là bạn đặt thời gian phù hợp với múi giờ hiện tại, biết múi giờ của các cột ngày giờ mà bạn lưu trữ và nhận thức được các vấn đề với thời gian tiết kiệm ánh sáng ban ngày.

Mặt khác, nếu bạn có quyền kiểm soát múi giờ của các máy chủ mà bạn làm việc thì bạn có thể đặt mọi thứ thành UTC trong nội bộ và không bao giờ phải lo lắng về múi giờ và DST.

Dưới đây là một số lưu ý mà tôi đã thu thập được về cách làm việc với múi giờ như một dạng bảng đánh lừa cho bản thân tôi và những người khác, điều này có thể ảnh hưởng đến múi giờ mà người đó sẽ chọn cho máy chủ của mình và cách họ sẽ lưu trữ ngày và giờ.

Bảng gian lận múi giờ của MySQL

Ghi chú:

  1. Thay đổi múi giờ sẽ không thay đổi ngày giờ hoặc dấu tối ưu hóa được lưu trữ , nhưng nó sẽ chọn một ngày giờ khác từ cột dấu tối ưu

  2. Cảnh báo! UTC có những giây nhuận, những giây này trông giống như '2012-06-30 23:59:60' và có thể được thêm ngẫu nhiên, với thông báo trước 6 tháng, do sự quay chậm lại của trái đất

  3. GMT gây nhầm lẫn giữa giây, đó là lý do tại sao UTC được phát minh.

  4. Cảnh báo! múi giờ khu vực khác nhau có thể tạo ra cùng một giá trị ngày giờ so với thời gian tiết kiệm ánh sáng ban ngày

  5. Cột dấu thời gian chỉ hỗ trợ các ngày từ 1970-01-01 00:00:01 đến 2038-01-19 03:14:07 UTC, do một hạn chế .

  6. Bên trong một cột dấu thời gian MySQL được lưu trữ dưới dạng UTC nhưng khi chọn một ngày, MySQL sẽ tự động chuyển đổi nó sang múi giờ phiên hiện tại.

    Khi lưu trữ một ngày trong dấu thời gian, MySQL sẽ giả định rằng ngày đó nằm trong múi giờ phiên hiện tại và chuyển đổi nó thành UTC forstorage.

  7. MySQL có thể lưu trữ từng phần ngày tháng trong các cột ngày giờ, những cột này trông giống như "2013-00-00 04:00:00"

  8. MySQL lưu trữ "0000-00-00 00:00:00" nếu bạn đặt cột ngày giờ làNULL, trừ khi bạn đặt riêng cột để cho phép null khi bạn tạo.

  9. Đọc phần này

Để chọn cột dấu thời gian ở định dạng UTC

bất kể múi giờ nào mà phiên MySQL hiện tại đang ở:

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

Bạn cũng có thể đặt máy chủ hoặc múi giờ toàn cầu hoặc múi giờ phiên hiện tại thành UTC và sau đó chọn dấu thời gian như sau:

SELECT `timestamp_field` FROM `table_name`

Để chọn ngày giờ hiện tại theo giờ UTC:

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

Kết quả mẫu:2015-03-24 17:02:41

Để chọn ngày hiện tại trong múi giờ phiên

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

Để chọn múi giờ đã được đặt khi máy chủ khởi chạy

SELECT @@system_time_zone;

Ví dụ:trả về "MSK" hoặc "+04:00" cho giờ Moscow, có (hoặc đã) một lỗi MySQL trong đó nếu được đặt thành bù số, nó sẽ không điều chỉnh thời gian tiết kiệm Ánh sáng ban ngày

Để nhận múi giờ hiện tại

SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP);

Nó sẽ trả về 02:00:00 nếu múi giờ của bạn là +2:00.

Để lấy dấu thời gian UNIX hiện tại (tính bằng giây):

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

Để lấy cột dấu thời gian làm dấu thời gian UNIX

SELECT UNIX_TIMESTAMP(`timestamp`) FROM `table_name`

Để lấy cột ngày giờ UTC làm dấu thời gian UNIX

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

Nhận ngày giờ của múi giờ hiện tại từ số nguyên dấu thời gian UNIX dương

SELECT FROM_UNIXTIME(`unix_timestamp_int`) FROM `table_name`

Nhận ngày giờ UTC từ dấu thời gian UNIX

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

Nhận ngày giờ của múi giờ hiện tại từ số nguyên dấu thời gian UNIX âm

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

Có 3 vị trí mà múi giờ có thể được đặt trong MySQL:

Lưu ý:Múi giờ có thể được đặt ở 2 định dạng:

  1. chênh lệch so với UTC:'+00:00', '+10:00' hoặc '-6:00'
  2. dưới dạng múi giờ được đặt tên:'Châu Âu / Helsinki', 'Hoa Kỳ / Phương Đông' hoặc 'MET'

Múi giờ đã đặt tên chỉ có thể được sử dụng nếu bảng thông tin múi giờ trong cơ sở dữ liệu mysql đã được tạo và điền.

trong tệp "my.cnf"

default_time_zone='+00:00'

hoặc

timezone='UTC'

@@ biến global.time_zone

Để xem chúng được đặt thành giá trị nào

SELECT @@global.time_zone;

Để đặt giá trị cho nó, hãy sử dụng một trong hai:

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

@@ biến session.time_zone

SELECT @@session.time_zone;

Để đặt nó, hãy sử dụng một trong hai:

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

cả "@@ global.time_zone biến" và "@@ session.time_zone biến" đều có thể trả về "SYSTEM", nghĩa là chúng sử dụng múi giờ được đặt trong "my.cnf".

Để tên múi giờ hoạt động (ngay cả đối với múi giờ mặc định), bạn phải thiết lập bảng thông tin múi giờ của mình cần được điền: http://dev.mysql.com/doc /refman/5.1/en/time-zone-support.html

Lưu ý:bạn không thể làm điều này vì nó sẽ trả về NULL:

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

Thiết lập bảng múi giờ mysql

Đối với CONVERT_TZ để làm việc, bạn cần điền bảng múi giờ

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` ;

Nếu chúng trống, hãy lấp đầy chúng bằng cách chạy lệnh này

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

nếu lệnh này cung cấp cho bạn lỗi " dữ liệu quá dài đối với cột 'viết tắt' ở hàng 1 ", thì có thể do ký tự NULL được thêm vào cuối chữ viết tắt của múi giờ

cách khắc phục để chạy cái này

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

(đảm bảo quy tắc dst máy chủ của bạn được cập nhật zdump -v Europe/Moscow | grep 2011 https://chrisjean.com/updating-daylight-saving-time- trên linux / )

Xem toàn bộ lịch sử chuyển đổi DST (Giờ tiết kiệm ánh sáng ban ngày) cho mọi múi giờ

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 cũng áp dụng mọi thay đổi DST cần thiết dựa trên các quy tắc trong các bảng trên và ngày bạn sử dụng.

Lưu ý:
Theo tài liệu > , giá trị bạn đặt cho múi giờ không thay đổi, ví dụ:nếu bạn đặt là "+01:00", thì múi giờ sẽ được đặt làm khoảng chênh lệch so với UTC, không tuân theo DST, vì vậy nó sẽ giữ nguyên tất cả quanh năm.

Chỉ múi giờ được đặt tên sẽ thay đổi thời gian vào giờ tiết kiệm ánh sáng ban ngày.

Các từ viết tắt như CET sẽ luôn là mùa đông và CEST sẽ là giờ mùa hè trong khi +01:00 sẽ luôn là UTC thời gian + 1 giờ và cả hai sẽ không thay đổi theo DST.

Hệ thống system múi giờ sẽ là múi giờ của máy chủ nơi mysql được cài đặt (trừ khi mysql không xác định được)

Bạn có thể đọc thêm về cách làm việc với DST tại đây

Khi nào không sử dụng UTC của Jon Skeet huyền thoại: https://codeblog.jonskeet.uk/2019/03/27/storing-utc-is-not-a-silver-bullet/ (Ví dụ:một sự kiện đã lên lịch trong tương lai đại diện cho thời gian, không phải tức thời)

câu hỏi liên quan:

Nguồn:



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tôi không thể lấy biểu mẫu đăng nhập của mình để kết nối tương tác đúng với cơ sở dữ liệu mySQL

  2. Quyền của người dùng MySQL

  3. Xóa hàng bằng MySQL LEFT JOIN

  4. Làm cách nào để lặp qua truy vấn MySQL qua PDO trong PHP?

  5. Nhiều truy vấn được thực thi trong java trong một câu lệnh