ทำไม Unix ถึงจัดเก็บการประทับเวลาในจำนวนเต็มที่ลงนามแล้ว?


24

ทำไมจำนวนเต็มที่ลงนามจึงถูกใช้เพื่อแทนการประทับเวลา? มีจุดเริ่มต้นที่ชัดเจนในปี 1970 ที่แสดงเป็น 0 ดังนั้นทำไมเราต้องใช้ตัวเลขก่อนหน้านั้น มีการใช้การประทับเวลาเชิงลบทุกที่หรือไม่


2
นั่นเป็นเหตุผลที่ Nostradamus ไม่สามารถใช้คอมพิวเตอร์ของเขาเพื่อเขียนคำทำนายของเขาสำหรับปี 3000 + ... มันจะทำให้เกิดการล้นและแสดงวันที่ของเขาเป็นลบ ฉันคิดว่าพวกเขาเรียกมันว่าบั๊ก Y3K หรืออะไรบางอย่าง!
Jeach

3
ชาวโรมันโบราณมีปัญหาที่เลวร้ายยิ่งเมื่อตัวเลขปีเปลี่ยนจากเชิงลบเป็นบวก พวกเขาจะเรียกมันว่าปัญหา Y0K หากพวกเขามีวิธีแสดงจำนวนศูนย์ 8-)}
Keith Thompson

คำตอบ:


35

เวอร์ชันแรกของ C ไม่มีจำนวนเต็มที่ไม่ได้ลงนาม (โปรแกรมเมอร์บางคนใช้พอยน์เตอร์เมื่อพวกเขาต้องการเลขคณิตที่ไม่ได้ลงชื่อ) ฉันไม่รู้ว่าอันไหนมาก่อนtime()ฟังก์ชั่นหรือประเภทที่ไม่ได้ลงนาม แต่ฉันสงสัยว่าการเป็นตัวแทนถูกสร้างขึ้นก่อนประเภทที่ไม่ได้ลงนาม และในปี 2038 ก็เพียงพอแล้วในอนาคตที่อาจไม่น่าเป็นห่วง ฉันสงสัยว่าหลายคนคิดว่า Unix จะยังคงมีอยู่ในตอนนั้น

ข้อดีอีกอย่างของการเซ็นชื่อtime_tคือการขยายไปถึง 64 บิต (ซึ่งกำลังเกิดขึ้นในบางระบบ) ช่วยให้คุณสามารถแสดงเวลาหลายร้อยพันล้านปีในอนาคตโดยไม่สูญเสียความสามารถในการเป็นตัวแทนครั้งก่อนปี 1970 (นั่นคือเหตุผลที่ฉันคัดค้านไม่ได้ลงชื่อ แบบ 32 บิตtime_tเรามีเวลาพอที่จะเปลี่ยนเป็น 64 บิต)


7
timeฟังก์ชั่นเก่ากว่ายุค: Unix v1 (ในปี 1971) นับในหน่วยของ 1 / 60th ของวินาทีจากเที่ยงคืนวันที่ 1971/01/01 มันเป็นข้อผิดพลาดที่รู้จักกันดี อยู่แล้วว่า“ ผู้ใช้ที่คำนึงถึงลำดับเหตุการณ์จะทราบว่า 2 * 32 sixtieths ของ asecond นั้นใช้เวลาเพียง 2.5 ปีเท่านั้น”unsignedเปิดตัวโดยK&R ในปี 1978หลังจากยุค 1970 ก่อตั้งขึ้น
Gilles 'ดังนั้นหยุดความชั่วร้าย'

ฉันทำการทดสอบอย่างรวดเร็วและในกล่อง 64 บิตของฉัน gmtimeและlocaltimeสูงสุดในปี 2147483647 (กับวินาทีถัดไปหลังจากให้ -2147483648 เป็นปี) ดังนั้นเพื่อให้ได้เวลา 55 บิตที่ผ่านมาบางคนจะต้องอัพเดตรูทีนเอาต์พุตเพื่อใช้ int 64- บิตสำหรับปีแทนที่จะเป็น int 32- บิตที่ไม่ได้ลงนาม หวังว่าใครบางคนจะดูแลบั๊กนั้นในอีกไม่กี่พันล้านปีข้างหน้า
Freiheit

@freiheit: น่าสนใจ ปัญหามีว่าstruct tmประเภทมีสมาชิกtm_year(คิดปีนับตั้งแต่ปี 1900) intซึ่งเป็นชนิด ระบบ 64 บิตสามารถมี 64 บิตtime_tแต่พวกเขามักจะมี int32 (ถ้าcharเป็น 8 บิตและint64 บิตก็shortสามารถเป็นได้ทั้ง 16 หรือ 32 บิตและจะไม่มีประเภทที่กำหนดไว้ล่วงหน้าสำหรับขนาดอื่น ๆ ) แต่time()อาจเป็นฟังก์ชั่นเดียวเท่านั้น<time.h>ที่ต้องใช้การสนับสนุนระดับระบบ คุณสามารถเขียนโค้ดของคุณเองเพื่อแปลงtime_tค่าเป็นสตริงที่มนุษย์อ่านได้
Keith Thompson

12

มันให้การสนับสนุนการประทับเวลาและวันที่ก่อนวันที่ 1 มกราคม 1970


1
สิ่งนี้ทำให้ 68 ปีที่ผ่านมา - 1902 ดูเหมือนว่าค่อนข้างน้อย
บากูดัน

2
POSIX ไม่จำเป็นต้องtime_tเป็น 32 บิตเท่านั้น มันมีอยู่แล้ว 64 บิตในหลาย ๆ ระบบ
Keith Thompson

1
mktime()ฟังก์ชันส่งคืน-1ในกรณีที่เกิดข้อผิดพลาดดังนั้นจึงเป็นไปไม่ได้ที่จะแยกแยะระหว่างการประทับเวลาที่ถูกต้องก่อน 1970-01-01 และข้อผิดพลาด ts ไม่อนุญาตให้มีการนัดล่วงหน้าก่อนวันที่ 1970-01-01
DimG

@DimG: 1969-12-31 23:59:59 UTCมันเป็นเรื่องยากที่จะแยกแยะความแตกต่างระหว่างข้อผิดพลาดและเวลาที่เฉพาะเจาะจง ค่าลบอื่น ๆ ที่นอกเหนือจาก-1นั้นจะไม่คลุมเครือ
Keith Thompson

1
@mtraceur: มาตรฐาน C ไม่จำเป็นต้องมีความล้มเหลวในการเรียกร้องให้ชุดmktime() errno(POSIX ทำ)
Keith Thompson
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.