Dường như không có vấn đề gì về múi giờ trên máy chủ miễn là bạn có 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 thời gian mà bạn lưu trữ và nhận thức được các vấn đề về 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 cùng thì bạn có thể đặt mọi thứ thành UTC trong nội bộ và không bao giờ lo lắng về múi giờ và DST.
Dưới đây là một số lưu ý tôi đã thu thập về cách làm việc với các múi giờ như một hình thức áo choàng cho bản thân và những người khác 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 anh ấy / cô ấy sẽ lưu trữ ngày và giờ.
MySQL Timezone Chcoateet
Ghi chú:
- Thay đổi múi giờ sẽ không thay đổi datetime hoặc dấu thời gian được lưu trữ , nhưng nó sẽ chọn một datetime khác từ các cột dấu thời gian
- Cảnh báo! UTC có giây nhảy vọt, chúng 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 tốc độ quay của trái đất chậm lại
GMT nhầm lẫn giây, đó là lý do tại sao UTC được phát minh.
Cảnh báo! các múi giờ khu vực khác nhau có thể tạo ra cùng một giá trị thời gian do thời gian tiết kiệm ánh sáng ban ngày
- Cột dấu thời gian chỉ hỗ trợ ngày 1970-01-01 00:00:01 đến 2038-01-19 03:14:07 UTC, do một giới hạn .
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 ngày, MySQL sẽ tự động chuyển đổi nó thành 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ẽ cho rằng ngày đó nằm trong múi giờ của phiên hiện tại và chuyển đổi nó thành UTC để lưu trữ.
- MySQL có thể lưu trữ một phần ngày trong các cột datetime, chúng 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 thời gian là NULL, trừ khi bạn đặc biệt đặt cột thành cho phép null khi bạn tạo nó.
- Đọc này
Để chọn cột dấu thời gian ở định dạng UTC
không có vấn đề gì về múi giờ của phiên MySQL hiện tại:
SELECT
CONVERT_TZ(`timestamp_field`, @@session.time_zone, '+00:00') AS `utc_datetime`
FROM `table_name`
Bạn cũng có thể đặt múi giờ của sever hoặc toàn cầu hoặc 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 thời gian hiện tại trong UTC:
SELECT UTC_TIMESTAMP();
SELECT UTC_TIMESTAMP;
SELECT CONVERT_TZ(NOW(), @@session.time_zone, '+00:00');
Kết quả ví dụ: 2015-03-24 17:02:41
Để chọn thời gian 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;
Chẳng hạn, trả về "MSK" hoặc "+04: 00" cho thời gian ở Matxcơva, có (hoặc là) một lỗi MySQL trong đó nếu được đặt thành bù số thì nó sẽ không điều chỉnh thời gian tiết kiệm ánh sáng ban ngày
Để có được 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 dưới dạng dấu thời gian UNIX
SELECT UNIX_TIMESTAMP(`timestamp`) FROM `table_name`
Để lấy cột thời gian UTC dưới dạng dấu thời gian UNIX
SELECT UNIX_TIMESTAMP(CONVERT_TZ(`utc_datetime`, '+00:00', @@session.time_zone)) FROM `table_name`
Nhận thời gian 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 thời gian 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 thời gian 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í nơi múi giờ có thể được đặt trong MySQL:
Lưu ý: Một múi giờ có thể được đặt ở 2 định dạng:
- phần bù từ UTC: 'EST: 00', '+10: 00' hoặc '-6: 00'
- dưới dạng múi giờ được đặt tên: 'Châu Âu / Helsinki', 'Hoa Kỳ / Miền Đông' hoặc 'MET'
Các múi giờ được đặt tên chỉ có thể được sử dụng nếu các bảng thông tin múi giờ trong cơ sở dữ liệu mysql đã được tạo và điền.
trong tập tin "my.cnf"
default_time_zone='+00:00'
hoặc là
timezone='UTC'
@@ biến toàn cầu.time_zone
Để xem giá trị nào chúng được đặt thành
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';
@@ session.time_zone
SELECT @@session.time_zone;
Để thiết lập, sử dụng một trong hai:
SET time_zone = 'Europe/Helsinki';
SET time_zone = "+00:00";
SET @@session.time_zone = "+00:00";
cả biến "@@ global.time_zone" và "@@ session.time_zone" có thể trả về "HỆ THỐNG" có nghĩa là họ 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 các 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
Để CONVERT_TZ
làm việc, bạn cần các bảng múi giờ được điền
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 cho cột 'viết tắt' ở hàng 1 ", thì có thể nguyên nhân là do một ký tự NULL được thêm vào cuối chữ viết tắt 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-on-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 time_zone không thay đổi, ví dụ: nếu bạn đặt nó là "+01: 00", thì time_zone sẽ được đặt thành phần bù từ UTC, do đó không tuân theo DST, do đó, không tuân theo DST, vì vậy nó sẽ giữ nguyên quanh năm
Chỉ các múi giờ được đặt tên sẽ thay đổi thời gian trong thời gian tiết kiệm ánh sáng ban ngày.
Chữ viết tắt như CET
sẽ luôn là thời gian mùa đông và CEST
sẽ là thời gian 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 với DST.
Các system
múi giờ sẽ là múi giờ của máy chủ nơi mysql được cài đặt (trừ khi mysql thất bại trong việc xác định nó)
Bạn có thể đọc thêm về làm việc với DST tại đây
Câu hỏi liên quan:
Nguồn: