ฉันได้ทำเครื่องหมายนี้เป็นวิกิชุมชนดังนั้นอย่าลังเลที่จะแก้ไขได้ตามอัธยาศัย
ปัญหาปี 2581 คืออะไร?
"ปัญหาปี 2038 (หรือที่เรียกว่า Unix Millennium Bug, Y2K38 โดยการเปรียบเทียบกับปัญหา Y2K) อาจทำให้ซอฟต์แวร์คอมพิวเตอร์บางตัวล้มเหลวก่อนหรือในปี 2038 ปัญหาดังกล่าวส่งผลกระทบต่อซอฟต์แวร์และระบบทั้งหมดที่จัดเก็บเวลาของระบบเป็นเซ็น 32 - จำนวนเต็มบิตและตีความตัวเลขนี้เป็นจำนวนวินาทีตั้งแต่ 00:00:00 UTC ของวันที่ 1 มกราคม 1970 "
เหตุใดจึงเกิดขึ้นและจะเกิดอะไรขึ้นเมื่อเกิดขึ้น?
ครั้งเกิน 03:14:07 UTC ของวันอังคารที่ 19 มกราคม 2038จะ 'ล้อมรอบ' และถูกจัดเก็บไว้ภายในเป็นจำนวนลบซึ่งระบบเหล่านี้จะตีความเป็นเวลาในวันที่ 13 ธันวาคม 1901 แทนที่จะเป็นปี 2038 เนื่องจาก ความจริงที่ว่าจำนวนวินาทีนับตั้งแต่ยุค UNIX (1 มกราคม 1970 00:00:00 GMT) จะเกินค่าสูงสุดของคอมพิวเตอร์สำหรับจำนวนเต็มที่มีลายเซ็น 32 บิต
เราจะแก้อย่างไร
- ใช้ชนิดข้อมูลแบบยาว (64 บิตก็เพียงพอแล้ว)
- สำหรับ MySQL (หรือ MariaDB) หากคุณไม่ต้องการข้อมูลเวลาให้พิจารณาใช้
DATE
ประเภทคอลัมน์ หากคุณต้องการความแม่นยำสูงใช้มากกว่าDATETIME
TIMESTAMP
ระวังว่าDATETIME
คอลัมน์จะไม่เก็บข้อมูลเกี่ยวกับเขตเวลาดังนั้นแอปพลิเคชันของคุณจะต้องทราบว่ามีการใช้เขตเวลาใด
- วิธีแก้ปัญหาที่เป็นไปได้อื่น ๆ ที่อธิบายไว้ใน Wikipedia
- รอให้ MySQL devs แก้ไขข้อบกพร่องนี้ที่รายงานเมื่อทศวรรษที่แล้ว
มีทางเลือกอื่นที่เป็นไปได้ในการใช้งานซึ่งไม่ก่อให้เกิดปัญหาในลักษณะเดียวกันหรือไม่?
ลองใช้ทุกที่ที่เป็นไปได้เพื่อใช้ประเภทขนาดใหญ่สำหรับการจัดเก็บวันที่ในฐานข้อมูล: 64 บิตเพียงพอแล้ว - ประเภทยาวแบบยาวใน GNU C และ POSIX / SuS หรือsprintf('%u'...)
ใน PHP หรือส่วนขยาย BCmath
มีกรณีใดบ้างที่อาจทำลายการใช้งานแม้ว่าเราจะยังไม่ถึงปี 2581
ดังนั้น MySQL DATETIMEจึงมีช่วง 1,000-9999 แต่ TIMESTAMP มีช่วง 1970-2038 เท่านั้น หากระบบของคุณจัดเก็บวันเกิดวันที่ส่งต่อในอนาคต (เช่นการจำนอง 30 ปี) หรือที่ใกล้เคียงกันแสดงว่าคุณกำลังประสบปัญหานี้อยู่แล้ว อีกครั้งอย่าใช้ TIMESTAMP ถ้าจะเป็นปัญหา
เราจะทำอย่างไรกับแอปพลิเคชันที่มีอยู่ซึ่งใช้ TIMESTAMP เพื่อหลีกเลี่ยงปัญหาที่เรียกว่าเมื่อมันเกิดขึ้นจริงๆ
แอปพลิเคชั่น PHP ไม่กี่ตัวที่จะยังคงใช้งานได้ในปี 2038 แม้ว่าจะยากที่จะมองเห็นได้เนื่องจากเว็บยังแทบจะไม่เป็นแพลตฟอร์มเดิม
นี่คือกระบวนการในการเปลี่ยนแปลงคอลัมน์ตารางฐานข้อมูลในการแปลงไปTIMESTAMP
DATETIME
เริ่มต้นด้วยการสร้างคอลัมน์ชั่วคราว:
# rename the old TIMESTAMP field
ALTER TABLE `myTable` CHANGE `myTimestamp` `temp_myTimestamp` int(11) NOT NULL;
# create a new DATETIME column of the same name as your old column
ALTER TABLE `myTable` ADD `myTimestamp` DATETIME NOT NULL;
# update all rows by populating your new DATETIME field
UPDATE `myTable` SET `myTimestamp` = FROM_UNIXTIME(temp_myTimestamp);
# remove the temporary column
ALTER TABLE `myTable` DROP `temp_myTimestamp`
ทรัพยากร