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ú:
-
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
-
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
-
GMT gây nhầm lẫn giữa giây, đó là lý do tại sao UTC được phát minh.
-
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
-
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ế .
-
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.
-
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"
-
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.
Để 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:
- chênh lệch so với UTC:'+00:00', '+10:00' hoặc '-6:00'
- 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.
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:
- Làm cách nào để đặt múi giờ của MySQL?
- MySql - CHỌN Cột TimeStamp ở định dạng UTC
- Cách thực hiện lấy dấu thời gian Unix trong MySQL từ giờ UTC?
- Chuyển đổi máy chủ MySQL TimeStamp To UTC
- https://dba. stackexchange.com/questions/20217/mysql-set-utc-time-as-default-timestamp
- Cách thực hiện Tôi nhận được múi giờ hiện tại của MySQL?
- Các trường ngày giờ trong MySQL và giờ tiết kiệm ánh sáng ban ngày - làm cách nào để tham khảo giờ" bổ sung "?
- Chuyển đổi giá trị âm từ FROM_UNIXTIME
Nguồn:
- https://bugs.mysql.com/bug.php?id=68861
- http:// dev. mysql.com/doc/refman/5.0/en/date-and-time-functions.html
- http://dev.mysql.com/doc/ refman / 5.1 / en / 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