Unix Timestamps & Epoch Time: The Year 2038 Problem, Explained

เผยแพร่เมื่อ: 9:00 AM , โดย ทีมงาน เวลาใน.com

อธิบาย Unix timestamp: วินาทีนับจากยุค 1970, การแปลง UTC, ปัญหาล้นในปี 2038 เวลา 03:14:07 UTC, การแก้ไขแบบ 64-bit และ leap seconds

หน้าจอนาฬิกาดิจิทัลที่เปลี่ยนจากเวลา 03:14:07 UTC ในวันที่ 19 มกราคม 2038 แสดงถึงการล้นของ Unix time แบบ signed 32-bit

Unix Timestamp คืออะไร?

Unix timestamp คือตัวเลขเดี่ยวๆ: จำนวนวินาทีที่ผ่านไปนับตั้งแต่ Unix epoch ซึ่งกำหนดไว้ที่ 00:00:00 UTC ของวันที่ 1 มกราคม ค.ศ. 1970 เท่านั้นเอง ไม่มีเขตเวลา ไม่มีสตริงวันที่ ไม่มีชื่อเดือน — เป็นเพียงจำนวนเต็มที่เพิ่มขึ้นทีละหนึ่งหน่วยต่อวินาที

เนื่องจาก epoch ถูกกำหนดไว้ตายตัวและเป็นสากล timestamp เช่น 1700000000 จึงหมายถึงช่วงเวลาที่แน่นอนเดียวกันทุกแห่งบนโลก เซิร์ฟเวอร์ในโตเกียวและแล็ปท็อปในชิคาโกจะเห็นพ้องต้องกันว่ามันหมายถึงวันที่ 14 พฤศจิกายน ค.ศ. 2023 เวลา 22:13:20 UTC การ แสดงผล ในท้องถิ่นจะแตกต่างกันไปตามเขตเวลา แต่ตัวเลขพื้นฐานไม่เคยเปลี่ยนแปลง

ข้อลดทอนความซับซ้อนโดยเจตนาประการหนึ่ง: Unix time ไม่สนใจอธิกวินาที (leap seconds) มันถือว่าทุกวันมี 86,400 วินาทีพอดี ซึ่งไม่เป็นความจริงนักในทางดาราศาสตร์ แต่ช่วยให้การคำนวณทางคณิตศาสตร์สะอาดและเรียบง่าย รายละเอียดเพิ่มเติมด้านล่าง

ทำไมวิศวกรถึงชอบมัน

Timestamp มีอยู่ทุกหนทุกแห่งในซอฟต์แวร์ — เวลาแก้ไขไฟล์, เรกคอร์ดฐานข้อมูล, การตอบสนองของ API, ฟิลด์วันหมดอายุของ JWT, บรรทัดบันทึก (log lines) — และด้วยเหตุผลที่ดี:

  • มันเป็นค่าเดียว จำนวนเต็มหนึ่งตัวเก็บวันที่และเวลาที่สมบูรณ์ ไม่ต้องแยกวิเคราะห์ ไม่มีความกำกวมระหว่าง MM/DD กับ DD/MM
  • มันไม่ขึ้นกับเขตเวลา ตัวเลขเป็น UTC เสมอ คุณจะแปลงเป็นเวลาท้องถิ่นก็ต่อเมื่อแสดงให้มนุษย์เห็นเท่านั้น
  • มันเปรียบเทียบและเรียงลำดับได้ง่ายดาย เหตุการณ์ไหนเกิดก่อน? จำนวนเต็มที่น้อยกว่า ระยะเวลาระหว่างสองเหตุการณ์? ลบกัน; คำตอบที่ได้อยู่ในหน่วยวินาที
  • มันจัดเก็บอย่างกะทัดรัด จำนวนเต็มขนาด 4 หรือ 8 ไบต์ เทียบกับสตริงที่จัดรูปแบบแล้ว

นี่คือเหตุผลที่โครงสร้างพื้นฐานจำนวนมากทำงานด้วย epoch seconds ภายใต้ฝาครอบ แม้ว่าอินเทอร์เฟซจะแสดงให้คุณเห็น 2026-07-23 ที่เป็นมิตรก็ตาม หากคุณต้องการย้ายระหว่างสองรูปแบบการแสดงผลนี้ ตัวแปลงการประทับเวลา Unix จะทำการแปลทั้งสองทิศทาง

การอ่าน Timestamp: ตัวอย่างเชิงปฏิบัติ

ลองใช้ timestamp 1000000000 — อันโด่งดัง เพราะมันครบรอบการหมุนเวียนในรายการโทรทัศน์สดท่ามกลางกลุ่มผู้ที่ชื่นชอบ Unix

ในการอ่านด้วยมือ คุณต้องหารวินาทีลงในหน่วยที่ใหญ่ขึ้น คร่าวๆ 1,000,000,000 วินาทีคือประมาณ 31.7 ปี (หนึ่งปีคือ ~31,556,952 วินาที) บวกกับ epoch ปี 1970 คุณจะไปถึงปี 2001 ช่วงเวลาที่แน่นอนคือ 09 กันยายน ค.ศ. 2001, 01:46:40 UTC

คุณแทบจะไม่ต้องคำนวณเลขคณิตนี้ด้วยตนเอง — ทุกภาษามีฟังก์ชันในตัว ใน Python:

```python from datetime import datetime, timezone datetime.fromtimestamp(1000000000, tz=timezone.utc)

2001-09-09 01:46:40+00:00

```

ประเด็นสำคัญ: การแปลงจะ ยึด UTC เป็นหลักเสมอ ฟังก์ชันจะเปลี่ยนจำนวนวินาทีดิบให้เป็นวันที่ในปฏิทินโดยการเดินหน้าไปจาก epoch หากคุณต้องการเวลาท้องถิ่นแทน คุณต้องใช้ค่าชดเชยเขตเวลา หลังจาก การแปลง UTC — ตัว timestamp เองไม่มีข้อมูลเขตเวลา

ปัญหาปี ค.ศ. 2038

นี่คือจุดที่เรื่องราวน่าสนใจ — และเป็นจุดที่ระบบที่ออกแบบมาอย่างดีจำนวนมากมีนาฬิกาที่กำลังเดินอยู่ภายใน

เป็นเวลาหลายทศวรรษที่ชนิดมาตรฐานของภาษา C ที่ใช้เก็บ Unix time คือ time_t ซึ่งโดยทั่วไปเป็น จำนวนเต็ม 32 บิตแบบมีเครื่องหมาย จำนวนเต็ม 32 บิตแบบมีเครื่องหมายสามารถแสดงค่าได้ตั้งแต่ −2,147,483,648 ถึง 2,147,483,647 ขอบเขตบนนี่คือปัญหา

นับวินาทีจาก epoch ปี 1970 ค่า 2,147,483,647 จะถึงที่ 03:14:07 UTC ของวันที่ 19 มกราคม ค.ศ. 2038 หนึ่งวินาทีต่อมา ตัวนับต้องกลายเป็น 2,147,483,648 — แต่ตัวเลขนั้นไม่พอดีกับจำนวนเต็ม 32 บิตแบบมีเครื่องหมาย แทนที่จะเพิ่มขึ้นต่อไป บิตจะ ล้นและวนกลับ ไปยังค่าลบมากที่สุด คือ −2,147,483,648

timestamp ที่เป็นลบจะถูกตีความเป็นเวลาที่ ก่อน epoch ดังนั้นนาฬิกาไม่ได้แค่หยุด — มันกระโดดถอยหลังไปยัง 13 ธันวาคม ค.ศ. 1901 ระบบใดก็ตามที่เชื่อถือ time_t ขนาด 32 บิตของมันจะจู่ๆ ก็เชื่อว่าตอนนี้เป็นช่วงต้นศตวรรษที่ 20

สิ่งนี้มักถูกเรียกว่า บั๊ก Y2K38 หรือ บั๊ก Unix Millennium Bug และในเชิงโครงสร้าง มันเป็นปัญหาการล้นของความกว้างคงที่แบบเดียวกับที่ขับเคลื่อนความตื่นตระหนกในปี ค.ศ. 2000 — เพียงแต่อยู่ไกลออกไปและมีรากฐานมาจากขีดจำกัดของจำนวนเต็มฐานสอง แทนที่จะเป็นปีสองหลัก

จุดที่มันส่งผลกระทบจริงๆ

เดสก์ท็อปและเซิร์ฟเวอร์ 64 บิตสมัยใหม่ได้รับการแก้ไขเป็นส่วนใหญ่เมื่อหลายปีก่อน ความเสี่ยงจะกระจุกตัวอยู่ในสถานที่ที่อัปเดตได้ยาก:

  • ระบบฝังตัวและระบบอุตสาหกรรม เราเตอร์, ตัวควบคุม, อุปกรณ์ทางการแพทย์, ชุดควบคุมอิเล็กทรอนิกส์ในรถยนต์ (ECU), และฮาร์ดแวร์ IoT ที่มาพร้อมกับ time_t ขนาด 32 บิต และอาจทำงานโดยไม่ถูกแตะต้องนานกว่า 20 ปี อุปกรณ์จำนวนมากที่ถูกนำไปใช้ ในปัจจุบัน จะยังคงให้บริการอยู่ในปี ค.ศ. 2038
  • โค้ด C แบบเดิม แอปพลิเคชันที่คอมไพล์โดยใช้คำจำกัดความ time_t แบบเก่า โดยเฉพาะอย่างยิ่งเมื่อชนิดข้อมูลนี้แทรกซึมเข้าไปในรูปแบบการจัดเก็บข้อมูลบนดิสก์หรือโปรโตคอลเครือข่าย
  • ฐานข้อมูลและระบบไฟล์เก่า รูปแบบการจัดเก็บข้อมูลที่ยัด timestamp ลงในฟิลด์ขนาด 32 บิต ระบบเก่าบางระบบแสดงอาการอยู่แล้วเมื่อต้องจัดการกับวันที่ในอนาคตอันไกล — ลองนึกถึงสินเชื่อบ้าน 20 ปี หรือใบรับรองที่หมดอายุซึ่งเลยปี ค.ศ. 2038 ไปแล้ว

รูปแบบความล้มเหลวไม่ได้เป็นการล่มอย่างรุนแรงเสมอไป บางครั้งมันเป็นการคำนวณวันที่ที่ผิดพลาดอย่างละเอียดอ่อน: โทเค็นที่หมดอายุแล้วซึ่งอ่านว่ายังใช้ได้, ลำดับการเรียงที่กลับด้าน, งานตามกำหนดการที่ทำงานในปี ค.ศ. 1901

วิธีแก้ไข: เวลา 64 บิต

การเยียวยานั้นตรงไปตรงมาในหลักการ — ขยาย time_t เป็น 64 บิต จำนวนเต็ม 64 บิตแบบมีเครื่องหมายสามารถนับวินาทีได้ไกลเกินขอบเขตในทางปฏิบัติใดๆ: จุดล้นอยู่ที่ประมาณ 292 พันล้านปี ในอนาคต ซึ่งสบายๆ เลยอายุขัยที่คาดหวังของดวงอาทิตย์ไปแล้ว

ระบบปฏิบัติการหลักส่วนใหญ่ในปัจจุบันได้ดำเนินการเปลี่ยนแปลงนี้แล้ว Linux 64 บิตใช้ time_t ขนาด 64 บิต; แม้แต่ Linux 32 บิตก็ได้รับการสนับสนุนเวลา 64 บิตในเคอร์เนลและ glibc ในช่วงไม่กี่ปีที่ผ่านมา ส่วนที่ยากไม่ใช่การแก้ไขตัวมันเอง — มันคือ การค้นหาและสร้างใหม่ เฟิร์มแวร์ทุกชิ้น, ทุกรูปแบบที่จัดเก็บไว้, และไบนารีของบุคคลที่สามทุกตัวที่ยังคงถือว่ามีขนาด 32 บิต งานตรวจสอบนั้นคือโครงการปี ค.ศ. 2038 ที่แท้จริง

อธิกวินาที (Leap Seconds) เข้ากันได้อย่างไร

เวลาทางดาราศาสตร์และเวลาอะตอมนั้นคลาดเคลื่อนเล็กน้อย ดังนั้น UTC อย่างเป็นทางการจึงแทรก อธิกวินาที เป็นครั้งคราวเพื่อให้นาฬิกาสอดคล้องกับการหมุนของโลก Unix time โดยการออกแบบ แสร้งทำเป็นว่าสิ่งเหล่านี้ไม่มีอยู่ — มันกำหนดตายตัวไว้ที่ 86,400 วินาทีต่อวัน

เมื่อเกิดอธิกวินาที ระบบต่างๆ มักจะ "smear" (กระจาย) มัน — โดยกระจายวินาทีพิเศษนั้นไปทั่วช่วงเวลาหนึ่ง (Google ทำให้การ smear แบบ 24 ชั่วโมงเป็นที่นิยม) เพื่อไม่ให้นาฬิกาใดต้องแสดง 23:59:60 ที่เป็นไปไม่ได้ ผลลัพธ์คือ: Unix timestamps ยังคงราบรื่นและเป็นโมโนโทนิก โดยมีค่าใช้จ่ายคือการคลาดเคลื่อนจาก UTC ที่เข้มงวดไปเพียงเสี้ยววินาทีเล็กน้อยในระหว่างการ smear สำหรับซอฟต์แวร์แทบทุกชนิด นี่คือการแลกเปลี่ยนที่คุณต้องการอย่างแท้จริง ปัญหาล้นปี ค.ศ. 2038 เป็นปัญหา ความกว้างของจำนวนเต็ม; อธิกวินาทีเป็นเรื่อง คำจำกัดความ ที่แยกต่างหากและเล็กกว่ามาก — อย่าสับสนระหว่างทั้งสอง

ข้อควรจำสำคัญ

  • Unix timestamp คือจำนวนวินาทีนับตั้งแต่ 00:00:00 UTC ของวันที่ 1 มกราคม ค.ศ. 1970 โดยไม่สนใจอธิกวินาที
  • มันเป็นจำนวนเต็มค่าเดียวที่ไม่ขึ้นกับเขตเวลา — ง่ายต่อการจัดเก็บ เปรียบเทียบ และเรียงลำดับ
  • การแปลงจะสัมพันธ์กับ UTC เสมอ เวลาท้องถิ่นจะถูกนำไปใช้ในภายหลัง
  • time_t ขนาด 32 บิตแบบมีเครื่องหมายจะล้นที่ 03:14:07 UTC ของวันที่ 19 มกราคม ค.ศ. 2038 โดยวนกลับเป็นค่าลบและกระโดดไปปี ค.ศ. 1901
  • วิธีแก้ไขคือ time_t ขนาด 64 บิต; ความพยายามอยู่ที่การตรวจสอบระบบฝังตัวและระบบแบบเดิม

อยากเห็นการทำงานจริงไหม? วางค่า epoch ใดๆ ลงใน ตัวแปลงการประทับเวลา Unix เพื่ออ่านเป็นวันที่มนุษย์อ่านได้ — หรือไปในทางกลับกันเพื่อเปลี่ยนวันที่ให้เป็น timestamp ของมัน

คำถามที่พบบ่อย

Unix timestamp อยู่ในหน่วยวินาทีหรือมิลลิวินาที?

Unix time แบบคลาสสิกอยู่ในหน่วย วินาที อย่างไรก็ตาม JavaScript และเว็บ API จำนวนมากใช้หน่วย มิลลิวินาที นับตั้งแต่ epoch ดังนั้นค่าเช่น 1700000000000 จึงมีขนาดใหญ่กว่า 1,000 เท่า วิธีสังเกตคร่าวๆ: timestamp ในหน่วยวินาทีสำหรับวันที่เมื่อเร็วๆ นี้จะมี 10 หลัก; แบบมิลลิวินาทีจะมี 13 หลัก หากไม่แน่ใจ ให้ตรวจสอบขนาดก่อนแปลง

ปัญหาปี ค.ศ. 2038 จะทำให้โทรศัพท์หรือแล็ปท็อปของฉันพังไหม?

แทบจะไม่แน่นอน ระบบปฏิบัติการ 64 บิตสมัยใหม่ใช้ time_t ขนาด 64 บิตอยู่แล้ว ซึ่งผลักดันจุดล้นออกไปอีกหลายพันล้านปี ความเสี่ยงที่แท้จริงอยู่ใน อุปกรณ์ฝังตัว ที่มีอายุการใช้งานยาวนานและซอฟต์แวร์เก่าที่ยังคงพึ่งพาเวลา 32 บิต และอาจไม่ได้รับการอัปเดตก่อนปี ค.ศ. 2038

Unix timestamp สามารถเป็นลบได้ไหม?

ได้ ค่าลบแสดงถึงช่วงเวลาที่ ก่อน epoch ปี ค.ศ. 1970 — ตัวอย่างเช่น -1 คือวันที่ 31 ธันวาคม ค.ศ. 1969 เวลา 23:59:59 UTC นี่คือสิ่งที่เกิดขึ้นเมื่อเกิดการล้นของ 32 บิตในปี ค.ศ. 2038 ซึ่งเป็นสาเหตุที่นาฬิกาดูเหมือนจะกระโดดกลับไปปี ค.ศ. 1901

ทำไม Unix time ถึงไม่สนใจอธิกวินาที?

เพื่อให้คณิตศาสตร์ง่ายและคาดเดาได้ การถือว่าทุกวันมี 86,400 วินาทีพอดี หมายความว่าระยะเวลาเป็นเพียงการลบ และ timestamps ยังคงเป็นโมโนโทนิก ความคลาดเคลื่อนเล็กน้อยกับ UTC ทางดาราศาสตร์ถูกจัดการโดยการ "smear" อธิกวินาที ซึ่งแอปพลิเคชันเกือบทั้งหมดชอบมากกว่าการจัดการกับกรณีขอบ 23:59:60

ฉันจะแปลง timestamp โดยไม่ต้องเขียนโค้ดได้อย่างไร?

ใช้เครื่องมือออนไลน์ ตัวแปลงการประทับเวลา Unix รับค่า epoch และแสดงวันที่และเวลา UTC และท้องถิ่นที่ตรงกันทันที และยังแปลงวันที่ในปฏิทินกลับเป็น timestamps ได้อีกด้วย

เวลาตอนนี้ ใน เมืองเหล่านี้:

นครนิวยอร์ก · ลอนดอน · โตเกียว · ปารีส · ฮ่องกง · สิงคโปร์ · ดูไบ · ลอสแองเจลิส · เซี่ยงไฮ้ · ปักกิ่ง · ซิดนีย์ · มุมไบ

เวลาปัจจุบันในประเทศ:

🇺🇸 สหรัฐอเมริกา | 🇨🇳 จีน | 🇮🇳 อินเดีย | 🇬🇧 สหราชอาณาจักร | 🇩🇪 เยอรมนี | 🇯🇵 ญี่ปุ่น | 🇫🇷 ฝรั่งเศส | 🇨🇦 แคนาดา | 🇦🇺 ออสเตรเลีย | 🇧🇷 บราซิล |

เวลาปัจจุบันใน เขตเวลา:

UTC | GMT | CET | PST | MST | CST | EST | EET | IST | จีน (CST) | JST | AEST | SAST | MSK | NZST |

ฟรี วิดเจ็ต สำหรับเว็บมาสเตอร์:

วิดเจ็ตนาฬิกาอนาล็อกฟรี | วิดเจ็ตนาฬิกาดิจิตอลฟรี | วิดเจ็ตนาฬิกาข้อความฟรี | วิดเจ็ตนาฬิกาคำฟรี