เวลาที่ผ่านไปนับจาก Epoch
(aphyr.com)- POSIX time/Unix time มักถูกเรียกว่าเป็นจำนวนวินาทีนับจาก 1970-01-01 00:00:00 แต่จริง ๆ แล้วเป็น ค่าที่อิง UTC โดยไม่สนใจ leap second จึงคลาดเคลื่อนจากจำนวนวินาทีที่ผ่านไปจริง
- ณ เวลา 2024-12-25 18:51:26 UTC ค่า POSIX time คือ 1735152686 ส่วนจำนวนวินาทีที่ผ่านไปจริงนับจาก epoch คือ 1735152713 วินาที จึงต่างกัน 27 วินาที
- IEEE 1003.1 กำหนด
seconds since the Epochโดยคำนวณหนึ่งวันเป็น 86,400 วินาที เสมอ และภาคผนวกของมาตรฐานก็ไม่สนใจ leap second 14 วินาทีที่เพิ่มเข้ามาหลังปี 1970 เพื่อความเข้ากันได้และความสะดวกในการคำนวณ - UTC เพิ่ม leap second เพื่อลดความต่างจากวันสุริยคติ และในจังหวะนั้น POSIX time จะกระโดดถอยหลัง ทำให้เกิดเหตุขัดข้องในกรณีอย่าง Linux, Qantas และ Cloudflare DNS
- สำหรับการวัดช่วงเวลาบนคอมพิวเตอร์เครื่องเดียว ควรใช้
CLOCK_MONOTONICหรือCLOCK_BOOTTIMEมากกว่า และถ้าจำเป็นต้องให้ตรงกับ POSIX timestamp ควรพิจารณาใช้ leap smear หรือการแปลง POSIX↔TAI
POSIX time ไม่ใช่จำนวนวินาทีที่ผ่านไปจริง
- JavaScript
Date, GNU coreutils, Linuxtime(2), Gotime.Unix, MySQLdatetime, RubyTime, Cassandratimestampฯลฯ มักปฏิบัติกับ POSIX time ราวกับเป็น จำนวนวินาทีนับจาก Unix epoch - แต่คำอธิบายนี้ไม่ตรงกับสัญชาตญาณทั่วไปอย่างแม่นยำ
- เวลาตัวอย่าง: 2024-12-25 18:51:26 UTC
- POSIX time: 1735152686
- จำนวนวินาทีที่ผ่านไปจริงนับจาก POSIX epoch: 1735152713
- ส่วนต่าง: 27 วินาที
- ความต่างนี้เกิดขึ้นเพราะ POSIX time แม้จะสืบทอดมาจาก UTC ใน IEEE 1003.1 แต่สมมติว่าทุกวันมีความยาวพอดี 86,400 วินาที
- นิยาม
seconds since the Epochในมาตรฐานคำนวณค่าด้วยtm_sec,tm_min,tm_hour,tm_yday,tm_yearและไม่ได้กำหนดความสัมพันธ์กับค่าที่เป็นปีก่อน 1970 หรือค่าติดลบ - ความยาวของหนึ่งวันจริงไม่ได้เป็น 86,400 วินาทีเสมอไป และเปลี่ยนแปลงตามเวลา
- นักดาราศาสตร์ประกาศ leap second เป็นระยะ เพื่อไม่ให้วันที่ตาม UTC ห่างจากวันสุริยคติมากเกินไป
- ผลคือ POSIX time อาจกระโดดถอยหลังได้ทุก ๆ หลายปี
- และสักวันหนึ่งก็อาจกระโดดไปข้างหน้าได้เช่นกัน
- leap second เคยนำไปสู่เหตุขัดข้องจริงมาแล้ว
- ปัญหา leap second ที่เกี่ยวข้องกับเคอร์เนล Linux
- ความล่าช้าของ Qantas จากบั๊ก leap second บน Linux
- ผลกระทบจาก leap second ต่อ Cloudflare DNS
การประนีประนอมของมาตรฐานและทางเลือกในงานจริง
- ภาคผนวก B ของ IEEE 1003 สรุปว่า ณ เวลาที่เผยแพร่มาตรฐาน มีการเพิ่ม leap second 14 ครั้ง หลัง 1970-01-01 แล้ว แต่เลือกไม่สนใจ 14 วินาทีนี้เพื่อให้คำนวณง่ายและเข้ากันได้
- มาตรฐานมองว่าค่า “time” ของระบบส่วนใหญ่เพิ่มขึ้นอย่างต่อเนื่อง และเลือกแนวทางว่าค่านี้ควรเพิ่มขึ้นแม้ระหว่าง leap second
- พร้อมกันนั้นยังตั้งสมมติฐานว่าระบบส่วนใหญ่ไม่ได้ติดตาม leap second หรืออาจไม่ได้ซิงก์กับมาตรฐานเวลาอ้างอิง
- ดังนั้นจึงไม่ได้กำหนดให้
seconds since the Epochจำเป็นต้องแทนจำนวนวินาทีที่ถูกต้องแม่นยำระหว่างเวลาอ้างอิงกับ epoch - แค่ให้แอปพลิเคชันปฏิบัติกับค่านี้เหมือนจำนวนวินาทีนับจาก epoch ได้ก็เพียงพอ ส่วนความแม่นยำที่ต้องการเป็นหน้าที่ของผู้ผลิตระบบและผู้ดูแลระบบในการปรับให้เหมาะสม
- ในแอปพลิเคชันแบบกระจาย ระบบใช้ timestamp เพื่อซิงก์เหตุการณ์ ดังนั้น การตีความที่สอดคล้องกัน อาจกลายเป็นเรื่องสำคัญ
- จำนวน leap second สะสมคาดการณ์ไม่ได้
- จำนวน leap second หลัง epoch มีแนวโน้มเพิ่มขึ้นได้
- มาตรฐานให้ความสนใจกับการซิงก์เวลาระหว่างแอปพลิเคชันในช่วงเวลาที่สั้นมากในเชิงดาราศาสตร์มากกว่า
- ระบบจริงโดยทั่วไปยังทำงานได้แม้เวลาจะคลาดเคลื่อนเล็กน้อย แต่ leap second เกิดขึ้นไม่บ่อย และ สัญชาตญาณเชิงเส้น ที่ว่า “จำนวนวินาทีนับจาก epoch” นั้นแข็งแรงมาก จนอาจมีบั๊กที่ยังไม่ถูกค้นพบสะสมอยู่
- ทางเลือกตามสถานการณ์มีดังนี้
- หากต้องคำนวณเฉพาะ duration ระหว่างสองเหตุการณ์บนคอมพิวเตอร์เครื่องเดียว ให้ใช้
CLOCK_MONOTONICหรือยิ่งไปกว่านั้นคือCLOCK_BOOTTIME - หากไม่จำเป็นต้องแลกเปลี่ยน timestamp กับระบบอื่นที่ถือว่าเป็น POSIX time ให้ใช้ TAI, GPS, LORAN
- หากต้องให้สอดคล้องโดยประมาณกับระบบ POSIX timestamp ให้ใช้ leap smear เพื่อกระจาย leap second ออกไปในช่วงเวลาที่ยาวขึ้น
- สามารถใช้ไลบรารีอย่าง t-a-i ของ qntm เพื่อแปลงระหว่าง POSIX กับ TAI ได้
- หากต้องคำนวณเฉพาะ duration ระหว่างสองเหตุการณ์บนคอมพิวเตอร์เครื่องเดียว ให้ใช้
- มี ความพยายามยกเลิก leap second กำลังดำเนินอยู่ และคาดหวังว่าจะเกิดขึ้นจริง ภายในปี 2035
- จำเป็นต้องมีงานเพิ่มเติมในการใส่ตารางแปลงให้กับทุกสิ่งที่พึ่งพาสมมติฐานว่า
หนึ่งวันมี 86,400 วินาที - สำหรับเวลาในช่วงหลังปี 2035 คำถามอย่าง “ระหว่างเวลาสองจุดมีอยู่กี่วินาที” อาจเรียบง่ายขึ้นมาก
- จำเป็นต้องมีงานเพิ่มเติมในการใส่ตารางแปลงให้กับทุกสิ่งที่พึ่งพาสมมติฐานว่า
1 ความคิดเห็น
ความคิดเห็นจาก Hacker News
เพิ่งอ่านนิยายไซไฟปี 2000 ของ Vernor Vinge เรื่อง A Deepness in the Sky จบ เป็นหนังสือยอดเยี่ยมที่มีการพูดถึง seconds since the epoch แบบคาดไม่ถึง
เริ่มจาก “ลองดูวิธีวัดเวลาของ Traders…” แล้วบรรยายว่า Qeng Ho นับเวลาเป็นวินาทีตั้งแต่วินาทีที่มนุษย์เหยียบดวงจันทร์ของ Old Earth เป็นครั้งแรก แต่เมื่อดูละเอียดขึ้น จุดเริ่มต้นจริง ๆ กลับอยู่หลังจากนั้นประมาณ 15 ล้านวินาที ซึ่งเป็นวินาทีที่ 0 ของระบบปฏิบัติการคอมพิวเตอร์ยุคแรก ๆ ของมนุษยชาติระบบหนึ่ง
ถ้าอยากได้ “วิทยาการคอมพิวเตอร์ในอวกาศ” มากขึ้น แนะนำซีรีส์ Bobiverse และถ้าอยากได้การสำรวจ “มนุษย์ + ซิมูเลชัน + คอมพิวเตอร์” มากขึ้น แนะนำ Permutation City
ทุกครั้งที่อ่านเรื่องการวัดเวลา จะได้เรียนรู้อะไรใหม่เสมอ ผมเคยคิดว่า Unix time เป็นวิธีติดตามเวลาที่เรียบง่ายที่สุด ถ้าพิจารณาแค่การ rollover และรู้เรื่อง leap second อยู่แล้ว แต่ไม่เคยคิดว่ามันมีผลกับเรื่องนี้ด้วย
ได้อ่านลิงก์ “UTC, GPS, LORAN and TAI” ด้วย และความจริงที่ว่าเวลา GPS ไม่สะท้อน leap second เป็นความต่างที่น่าสนใจ
ผมไม่ค่อยชอบแผนที่ว่า “มีความพยายามจะเลิกใช้ leap second ภายในปี 2035”
แก่นของ UTC คือการอยู่ห่างจาก TAI เป็นจำนวนวินาทีเต็ม และอยู่ใกล้ค่าเวลาแสงอาทิตย์เฉลี่ย (MST) หากจะไม่ติดตาม MST อีกแล้ว ก็ควรเปลี่ยนไปใช้ TAI เลย
ถ้าปล่อยให้ UTC ห่างจาก MST ไปเรื่อย ๆ ก็ยังต้องจัดการ leap second ในอดีตต่อไป แต่ leap second เหล่านั้นจะกลายเป็น สภาพก้ำกึ่ง ที่ไม่มีจุดประสงค์อีกแล้ว
อย่างไรก็ตาม ข้อเสนอนี้ก็ไม่ได้ไร้ความหมายโดยสิ้นเชิง เป้าหมายคือไม่เปลี่ยน การจัดการเวลา UTC ที่มีอยู่ แต่ทำให้ผลต่างระหว่าง timestamp สองตัวหลังปี 2035 กลายเป็นจำนวนวินาทีทางกายภาพที่ถูกต้อง
ถึงอย่างนั้น ในเมื่อ MST เป็นฟังก์ชันของ UTC อยู่แล้ว การตัดมันออกก็ดูตลกอยู่ดี
แต่ในความเป็นจริง ระบบจำนวนมากเลือกผิด โดยเฉพาะ UNIX ที่เป็นต้นเหตุใหญ่ที่สุด ทางเลือกนั้นฝังลึกอยู่ในระบบและข้อกำหนดจำนวนนับไม่ถ้วน จนการ “เปลี่ยนไปใช้ TAI เฉย ๆ” แทบเป็นไปไม่ได้
ดังนั้นการตีความ UTC ใหม่ให้เป็น “TAI ตัวใหม่” จึงง่ายกว่า และคงไม่น่าแปลกใจถ้าวันหนึ่ง UTC แบบเดิมจะกลับมาอีกครั้งภายใต้ชื่ออื่น
ในประเทศส่วนใหญ่หรือทั้งหมด เวลาพลเรือนอิงกับ UTC จะไม่มีใครหมุนนาฬิกาทั่วโลกย้อนหลังไปราว 30 วินาทีเพียงเพราะมันบริสุทธิ์กว่านิดหน่อย
เวลา GPS ก็มี offset กับ TAI แต่ไม่มีใครสนใจมากนัก Unix epoch ก็เช่นกัน แค่ผลลัพธ์สอดคล้องกันก็พอ
Leap_Secondทุกเดือนให้ดูว่ามีไฟล์นี้หรือเปล่า ถ้ามีก็ลบ แล้วเพิ่มค่าในไฟล์Leap_Secondsขึ้น 1 และสร้างแบ็กอัปชื่อLSSE“You are not expected to understand this.” เป็นวิธีคงทั้งสองระบบไว้ จะทำเป็นแฮชหรือตารางค้นหาก็ได้ถ้าต้องการ
อีกจุดที่สำคัญคือ UTC epoch สมัยใหม่คือวันที่ 1 มกราคม 1972 ก่อนหน้านั้น UTC ใช้ความยาววินาทีต่างจาก TAI
ปลายปี 1971 มีขั้นกลางเป็นการกระโดดไม่สม่ำเสมอครั้งสุดท้ายที่มีค่าเท่ากับ 0.107758 วินาที TAI พอดี และมีการปรับให้ผลรวมของขั้นเวลาเล็ก ๆ และการปรับความถี่ของ UTC หรือ TAI ในช่วงปี 1958–1971 เท่ากับ 10 วินาทีพอดี ดังนั้น 1972-01-01 00:00:00 UTC จึงตรงกับ 1972-01-01 00:00:10 TAI พอดี และหลังจากนั้นความต่างก็เป็นจำนวนวินาทีเต็ม
ในขณะเดียวกัน อัตราการ tick ของ UTC ก็เท่ากับ TAI พอดี และ UTC เริ่มติดตาม UT1 แทน UT2 ดังนั้น Unix time ในปี 1970 และ 1971 จึงไม่ตรงกับเวลา UTC จริงของช่วงนั้น
https://en.wikipedia.org/wiki/Coordinated_Universal_Time#His...
https://en.wikipedia.org/wiki/Unix_time#UTC_basis
แม้จะสมมติว่าเวลาในสูติบัตรแม่นยำถึงระดับวินาทีก็ตาม เพราะในบางช่วงชีวิตของคนนั้น ค่าที่ถือว่าเป็น “ความยาวของ 1 วินาที” ต่างจาก 1 วินาทีที่เรามักนึกถึงในปัจจุบันพอสมควร
วินาทีในที่นี้หมายถึงวินาทีตามเกณฑ์ความถี่การเปลี่ยนผ่านไฮเปอร์ไฟน์ของสถานะพื้นไม่ถูกรบกวนของอะตอมซีเซียม-133 ที่ 9,192,631,770 ครั้งต่อวินาที
เมื่อไม่นานมานี้ผมเขียนโค้ดสำหรับตลาดซื้อขายแห่งหนึ่ง ระบบนั้นรันอยู่บน VAX หรือพูดให้แม่นคือบน OpenVMS และมี epoch เป็นวันที่ 17 พฤศจิกายน 1858
นี่เป็นครั้งแรกในชีวิตการทำงานที่ผมเห็น epoch ที่ไม่ใช่ Unix และโชคดีที่โค้ดที่ใช้ถูกทำ abstraction ให้เป็น Unix epoch แล้ว
https://www.slac.stanford.edu/~rkj/crazytime.txt
เพื่อให้วันที่เหล่านี้พอดีกับหน่วยความจำคอมพิวเตอร์ในทศวรรษ 1950 จึงเลื่อนปฏิทินด้วย offset 2.4 ล้านวัน และผลคือวันที่ 0 กลายเป็น 17 พฤศจิกายน 1858
https://www.joelonsoftware.com/2006/06/16/my-first-billg-rev...
API ของ macOS/Swift Foundation อย่าง
NSDate.timeIntervalSinceReferenceDateใช้วันที่ 1 มกราคม 2001 เป็น epochWikipedia ก็มีรายการที่มีประโยชน์เช่นกัน: https://en.wikipedia.org/wiki/Epoch_(computing)#Notable_epoc...
บางช่วงเวลาไม่สามารถแสดงเป็น POSIX timestamp ได้ และ POSIX timestamp บางค่าก็จะไม่สอดคล้องกับเวลาจริง
มันคล้ายกับการบอกว่ามีบางช่วงเวลาที่ไม่มีปีตาม ISO 8601 ทุกช่วงเวลามีปี เพียงแต่บางปีมีความยาวมากกว่าปีอื่นเท่านั้น
ถ้านั่งดู https://time.is/UTC เวลาเวลาจะเพิ่มขึ้นแบบ monotonic และบางครั้งวินาทีบางวินาทีก็แค่ยาวขึ้นเล็กน้อยมาก เช่น ยาวขึ้นประมาณ 0.001% ตลอด 24 ชั่วโมง
เวลาเก็บวันที่ในฐานข้อมูล ผมเก็บเป็น Unix epoch time เสมอ และไม่บันทึกข้อมูล time zone ไว้ในฟิลด์วันที่ ถ้ามี requirement ที่ต้องรู้ time zone ก็เก็บแยกต่างหาก
เลยสงสัยว่าควรเก็บ timestamp เป็นรูปแบบ TAI แทน แล้วใช้ฟังก์ชันแปลงเป็น UTC เมื่อจำเป็น เพื่อจัดการการปรับแก้ที่เกี่ยวกับโลกเมื่อจำเป็นหรือไม่
รู้ว่า time zone เป็นดงกับระเบิด แต่ถึงอย่างนั้นมันก็เป็นสิ่งที่มนุษย์กำหนดขึ้น โดยเส้นแบ่ง time zone เปลี่ยนไปตามเวลา น่าจะต้องตรึงกับเวลาแบบ absolute แล้วค่อย render เป็นรูปแบบเวลา local ที่ต้องการเมื่อจำเป็น
การปรับ leap second ควรเกิดในจุดเดียวกับการแปลง time zone น่าเสียดายที่ Unix ทำสิ่งที่ผิดให้กลายเป็นมาตรฐาน และการ migrate ก็ทำได้ยาก
ดังนั้นนาฬิกาทั้งหมดก็ถูกตั้งให้ตรงกับ UTC อยู่ดี การแปลงจาก UTC เป็น TAI ตอนบันทึก แล้วแปลงกลับอีกตอนอ่าน จะทำให้ยุ่งเหยิง
โดยปกติฐานข้อมูลจะไม่มีแนวคิดเรื่อง time zone สำหรับ timestamp ที่เก็บไว้ (SQL Server) หรือมีชนิด timestamp แบบ “รู้ time zone” แต่จะแปลงอินพุตเป็น UTC แล้วทิ้ง time zone เดิมไป (MySQL, Postgres)
เท่าที่รู้ มีเพียง Oracle เท่านั้นที่สามารถ round-trip time zone ที่ไม่ใช่ local ไว้ได้จริงในชนิด
with time zoneในการคำนวณบางแบบ ความต่าง 1 วินาทีเป็นเรื่องใหญ่ เมื่อเลือกใช้รูปแบบที่ไม่ใช่รูปแบบที่ใช้กันแพร่หลายที่สุด ต้องระวัง และต้องมีเหตุผลที่ดีพอในการออกนอกมาตรฐาน แค่ความจริงที่ว่ามันต่างออกไปก็อาจมีต้นทุนสูงแล้ว
บทความนี้ทำให้รู้สึกเหมือนคริสต์มาสพังไปเลย ไม่มีอะไรศักดิ์สิทธิ์แล้วหรือไง? วินาทีควรเป็นวินาทีหลัง epoch สิ
ไม่เข้าใจว่าทำไมต้องสนใจการเบี่ยงจาก solar day เล็กน้อยด้วย ตัวแปลงจากวินาทีหลัง epoch ไปเป็นการแสดงวันที่ควรรับผิดชอบการปรับแก้ไม่ใช่หรือ?
เราไม่อยากให้ซอฟต์แวร์ทุกตัวต้อง hardcode การใส่ leap second, จัดการ smearing และต้องมีวิธีอัปเดตภายในหนึ่งเดือนเมื่อมีการเพิ่ม leap second ใหม่
จนถึงตอนนี้เราไม่ต้องกังวลหรือคิดถึงมัน และต่อไปก็ไม่จำเป็นต้องทำเช่นนั้น มันถูกจัดการด้วยวิธีที่ถูกต้องอยู่แล้ว
ควรแทนที่ leap second ด้วย จรวดขนาดใหญ่ ที่ติดตั้งบริเวณเส้นศูนย์สูตร อย่าปรับนาฬิกา ปรับดาวเคราะห์แทน
ในเรื่องเล่าตามคติอิสลามเกี่ยวกับวันสิ้นโลกและมารร้ายดัจญาล (Dajjal) ก็มีท่อนที่เกิดเรื่องทำนองนี้จริง ๆ อยู่ด้วย “วันแรกของดัจญาลจะยาวเหมือนหนึ่งปี วันที่สองจะยาวเหมือนหนึ่งเดือน และวันที่สามจะยาวเหมือนหนึ่งสัปดาห์” หลายคนตีความตามตัวอักษรว่าเป็นเหตุการณ์ระดับจักรวาลที่การหมุนของโลกช้าลงจริง ๆ และสุดท้ายทิศทางกลับด้านจนดวงอาทิตย์ขึ้นทางทิศตะวันตก นั่นคือสัญญาณสุดท้ายของการสิ้นสุดของมนุษยชาติ
แม้เพราะวินาทีอธิกสุรทินจะทำให้ epoch กลายเป็นอดีตที่นานกว่า 29 วินาทีเมื่อเทียบกับสิ่งที่
date +%sบอกเป็นนัย แล้วมันจะสำคัญอะไรสิ่งที่สำคัญกว่ามากคือข้อเท็จจริงที่ว่าทุกคนเห็นพ้องกันกับตัวเลข N ตัวหนึ่งที่แทนเวลาปัจจุบัน วินาที -29 ที่เป็นเพียงสมมติไม่ได้ส่งผลต่อโลกจริงเสียหน่อย เราคงไม่ได้จะไปรันรูทีนเล็งขีปนาวุธใส่เป้าหมายเมื่อ 30 ปีก่อนใช่ไหม
ผมเห็นด้วยกับการยกเลิกวินาทีอธิกสุรทิน แต่ไม่คิดว่าการเน้นความไม่ตรงกันของเวลาจะมีประโยชน์ ถึงแม้ว่าถ้าพูดกันตามจริงมันจะถูกต้องก็ตาม
ที่สำคัญกว่าคือผลกระทบต่ออนาคต ข้อที่ว่า timestamp ในอดีตอาจต่างจากการคำนวณง่าย ๆ แบบ “ตอนนี้ - N วินาที” ไปไม่กี่วินาทีนั้น โดยมากก็แค่เป็นข้อเท็จจริงที่น่าสนใจ แต่ข้อที่ว่า ณ เวลาใดเวลาหนึ่งในอนาคต นาฬิกาทั้งหมดอาจต้องขยับอีก 1 วินาที นั้นสำคัญกว่า มีกรณีจริงมากมายที่ต้องใช้ความพยายามไม่น้อยเพื่อคำนึงถึงเรื่องนี้