ติดตามคำถามของ /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
นี่คือบันทึกบางส่วนที่ฉันเก็บรวบรวมวิธีการทำงานกับเขตเวลาเป็นรูปแบบของ cheatsheet สำหรับฉันและผู้อื่นซึ่งอาจมีผลต่อเขตเวลาที่บุคคลจะเลือกสำหรับเซิร์ฟเวอร์ของเขาและวิธีที่เขา / เธอจะจัดเก็บวันที่และเวลา
หมายเหตุ:
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)
หมายเหตุ: เขตเวลาสามารถตั้งค่าได้ 2 รูปแบบ:
เขตเวลาที่มีชื่อสามารถใช้งานได้ต่อเมื่อตารางข้อมูลโซนเวลาในฐานข้อมูล 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 variable" และ "@@ session.time_zone variable" อาจกลับมา "SYSTEM" ซึ่งหมายความว่าพวกเขาใช้ timezone set ใน "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`
ใน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
ชุดmodified
= '2016/07/07 08:10 00: 00'
UNIX_TIMESTAMP(NOW());
ใช้งานของคุณโดยCONVERT_TZ()
ที่หนึ่งในพารามิเตอร์คือ `@@ session.time_zone สำหรับการแปลงชุดข้อมูล UTC เป็นเวลาประทับ UNIX อย่างน่าเชื่อถือคุณต้องตั้งค่าช่วงเวลา time_zone ก่อน
นี่คือตัวอย่างการทำงาน:
jdbc:mysql://localhost:3306/database?useUnicode=yes&characterEncoding=UTF-8&serverTimezone=Europe/Moscow
PHP และ MySQL มีการกำหนดค่าเขตเวลาเริ่มต้นของตนเอง คุณควรซิงโครไนซ์เวลาระหว่างฐานข้อมูลของคุณกับเว็บแอปพลิเคชันมิฉะนั้นคุณสามารถเรียกใช้บางประเด็นได้
อ่านบทช่วยสอนนี้: วิธีซิงโครไนซ์ PHP และเขตเวลา MySQL ของคุณ
date_default_timezone_set("America/Los_Angeles");
และmysql_query("SET time_zone='" . date('P', time()) . "'");
ทำงานได้อย่างสวยงามมาก!
ข้อดีและข้อเสียนั้นเหมือนกันมากขึ้นอยู่กับว่าคุณต้องการสิ่งนี้หรือไม่
ระวังถ้าเขตเวลา MySQL แตกต่างจากเวลาระบบของคุณ (เช่น PHP) การเปรียบเทียบเวลาหรือการพิมพ์ไปยังผู้ใช้จะเกี่ยวข้องกับการแก้ไขบางอย่าง