ไฟล์จะถูก 'สร้าง' ในปี 1641 ได้อย่างไร?


75

ไม่กี่ปีที่ผ่านมาฉันสะดุดไฟล์นี้ในไฟล์เซิร์ฟเวอร์ของเรา

สกรีนช็อตของกล่องโต้ตอบคุณสมบัติไฟล์ใน Microsoft Windows

และฉันสงสัยว่าไฟล์จะบอกว่ามันถูกสร้างขึ้นในปี 1641 ได้อย่างไร เท่าที่ฉันรู้เวลาบนพีซีถูกกำหนดโดยจำนวนวินาทีตั้งแต่วันที่ 1 มกราคม 1970 หากดัชนีนั้นบกพร่องคุณสามารถรับ 31 ธันวาคม 1969 (ดัชนีอาจบอกว่า -1) แต่ฉันนิ่งงันกับสิ่งนี้ ดูเหมือนว่าจะสุ่มวันที่ถือกำเนิดขึ้นแม้กระทั่งการก่อตั้งของสหรัฐอเมริกา

ดังนั้นไฟล์สามารถลงวันที่ใน 1641 ได้อย่างไร?

PS: วันที่เป็นภาษาฝรั่งเศส Févrierคือเดือนกุมภาพันธ์


29
"เท่าที่ฉันรู้เวลาบนพีซีถูกกำหนดโดยจำนวนวินาทีตั้งแต่วันที่ 1 มกราคม 1970" - แม้สำหรับระบบที่เป็นอยู่วันที่ก่อนปี 1970 จะแสดงได้อย่างง่ายดายโดยการทำให้จำนวนนั้น (เรียกว่าการประทับเวลาแบบยูนิกซ์ ) เป็นค่าลบ ตัวอย่างเช่นเวลายูนิกซ์ -1000000000 สอดคล้องกับ 1938-04-24 22:33:20
marcelm

1
@marcelm ใช่ แต่วันที่ต่ำสุดที่เป็นไปได้คือในปี 1901 เนื่องจากช่วงที่ จำกัด ของจำนวนเต็ม 32 บิต
slhck

14
@slhck: ฉันคิดว่า marcelm ใช้เวลาประทับ 64 บิตเพราะนั่นคือสิ่งที่ระบบไฟล์ Unix / Linux ปัจจุบัน, เคอร์เนลและซอฟต์แวร์พื้นที่ผู้ใช้ใช้ ดูclock_gettime(2)man pageสำหรับคำจำกัดความstruct timespecซึ่งเป็นสิ่งที่statและการเรียกระบบอื่นใช้เพื่อส่งการประทับเวลาระหว่างพื้นที่ผู้ใช้และเคอร์เนล มันเป็นโครงสร้างที่มีtime_tในไม่กี่วินาทีและlong tv_nsecนาโนวินาที บนระบบ 64 บิตทั้งสองเป็น 64 บิตดังนั้นการประทับเวลาทั้งหมดคือ 128 บิต (16 ไบต์) (ขออภัยในรายละเอียดที่มากเกินไปฉันถูกพาไป)
Peter Cordes

3
คุณได้รับคำตอบที่ดีว่าวันที่ใน 1600s สามารถถูกประทับลงในไฟล์ได้อย่างไรตอนนี้ถึงเวลาที่จะไตร่ตรองว่ามันเกิดขึ้นได้อย่างไร ฉันจะดูเนื้อหาของไฟล์ wp นั้นอย่างใกล้ชิดเพื่อดูว่าอาจมีการเพิ่มอะไรลงไปบ้าง ฉันจะดูปลั๊กอินที่ติดตั้งและตรวจสอบว่าไม่มีความร่มรื่น ฉันคิดว่ามีบางสิ่งที่แก้ไขไฟล์นั้นและพยายามประทับตราวันที่แก้ไข / สร้างด้วยตนเองเพื่อซ่อนว่าไฟล์นั้นถูกแก้ไข แต่ระบุเวลา unix แทนเวลา windows
โทมัสคาร์ไลเซิล

2
King Louis XIII the Just แสดงให้เห็นถึงความมุ่งมั่นของราชวงศ์ที่มีต่อ PHP?
Jesse Slicer

คำตอบ:


106

เหตุใดจึงเป็นวันที่จาก 1600s เป็นไปได้?

Windows ไม่เก็บ timestamps ไฟล์มีการแก้ไขเช่นระบบปฏิบัติการ Unix ทำ ตามWindows Dev Center (เหมืองเน้น):

เวลาไฟล์คือค่า 64- บิตที่แทนจำนวนช่วงเวลา 100 นาโนวินาทีที่ผ่านไปตั้งแต่ 12:00 AM วันที่ 1 มกราคม 1601 Coordinated Universal Time (UTC) ระบบบันทึกเวลาไฟล์เมื่อแอปพลิเคชั่นสร้างเข้าถึงและเขียนลงไฟล์

ดังนั้นด้วยการตั้งค่าผิดที่นี่คุณสามารถรับวันที่จาก 1600s

แน่นอนคำถามสำคัญอีกข้อหนึ่งคือ: ชุดนี้มีค่าอย่างไร? วันที่แท้จริงคืออะไร? ฉันคิดว่าคุณจะไม่สามารถหาคำตอบได้เนื่องจากเป็นข้อผิดพลาดในการคำนวณในไดรเวอร์ระบบไฟล์ คำตอบอีกข้อหนึ่งตั้งสมมติฐานว่าวันที่นี้เป็นจริงของการประทับเวลา Unix ตีความว่าเป็นการประทับเวลาของ Windows แต่จริง ๆ แล้วพวกเขาจะคำนวณตามช่วงเวลาที่แตกต่างกัน (วินาทีกับ nanoseconds)

สิ่งนี้เกี่ยวข้องกับปัญหาปี 2038 อย่างไร

การใช้ชนิดข้อมูล 64 บิตหมายความว่า Windows (โดยทั่วไป) ไม่ได้รับผลกระทบจากปัญหาปี 2038ที่ระบบ Unix ดั้งเดิมมีเนื่องจาก Unix เริ่มใช้จำนวนเต็ม 32 บิตซึ่งล้นเร็วกว่าจำนวนเต็ม 64 บิตที่ Windows มี (นี่คือแม้ Unix ปฏิบัติการในไม่กี่วินาทีและ Windows ทำงานบนไมโคร / nanoseconds.)

Windows ยังคงได้รับผลกระทบเมื่อใช้โปรแกรม 32 บิตที่คอมไพล์ด้วย Visual Studio เวอร์ชันเก่าแน่นอน

ระบบปฏิบัติการ Unix รุ่นใหม่ได้ขยายประเภทข้อมูลไปเป็น 64 บิตแล้วจึงหลีกเลี่ยงปัญหานี้ได้ (อันที่จริงแล้วเนื่องจากการประทับเวลาของ Unix ทำงานในไม่กี่วินาทีวันที่ขึ้นใหม่จะอยู่ที่ 292 พันล้านปีจากนี้)

วันที่สูงสุดที่สามารถตั้งค่าคืออะไร?

สำหรับคนที่อยากรู้อยากเห็น - นี่คือวิธีการคำนวณ:

  • จำนวนของค่าที่เป็นไปได้ในจำนวนเต็ม 64 บิตเป็น2 63 - 1 n = 9223372036854775807
  • แต่ละเห็บหมายถึง 100 นาโนวินาทีซึ่งก็คือ 0.1 µs หรือ 0.0000001 s
  • ช่วงเวลาสูงสุดจะเป็น9223372036854775807 ⨉ 0.0000001 sดังนั้นหลายร้อยพันล้านวินาที
  • หนึ่งชั่วโมงมี 3600 วินาทีหนึ่งวันมี 86400 วินาทีและหนึ่งปีมี 365 วันดังนั้นมี86400 ⨉ 365 s = 31536000 sในหนึ่งปี แน่นอนนี่เป็นเพียงค่าเฉลี่ยไม่สนใจปีอธิกสุรทินวินาทีอธิกวินาทีหรือการเปลี่ยนแปลงปฏิทินใด ๆ ที่ระบอบ postapocalyptic ในอนาคตอาจกำหนดบนพื้นดินที่เหลือ
  • 9223372036854775807 ⨉ 0.0000001 s / 31536000 s ≈ 29247 ปี
  • @corsiKaอธิบายวิธีที่เราสามารถลบการก้าวกระโดดปี: 29247/365/4 ≈ 20
  • ดังนั้นปีสูงสุดของคุณคือ1601 + 29247-20 = 30828

บางคนพยายามที่จะตั้งค่านี้และเกิดขึ้นในปีเดียวกัน


7
สำหรับเร็กคอร์ด Unix (หรืออย่างน้อย Linux) ได้แก้ไขปัญหา 2038 สำหรับเคอร์เนล / ระบบแฟ้มบนสถาปัตยกรรม 64- บิตซึ่ง time_tเป็นประเภท 64 บิตดังนั้นแอปพลิเคชันที่หวังว่าจะใช้time_tแทนประเภทจำนวนเต็มที่ยังคงเป็น 32 บิตและ จะตัดทอนการประทับเวลา ... อย่างไรก็ตามในกรณีที่มีใครอยากรู้เกี่ยวกับสถานะของปัญหานั้นส่วนใหญ่จะได้รับการแก้ไขยกเว้นมรดก 32 บิต IDK ถ้า ARM 32 บิตจะยังคงมีความเกี่ยวข้องในปี 2581 แต่สิ่งนี้จะบังคับให้เปลี่ยน ABI เป็นอย่างน้อย x86 แบบ 32 บิตนั้นหายไปในโลกยูนิกซ์ เป็น Windows เท่านั้นที่ยังใช้รหัส 32 บิตอยู่
Peter Cordes

ความคิดเห็นไม่ได้มีไว้สำหรับการอภิปรายเพิ่มเติม การสนทนานี้ได้รับการย้ายไปแชท
Journeyman Geek

1
เวลา VMS คือ " ค่า 64 บิตที่แทนจำนวนช่วงเวลา 100 นาโนวินาทีที่ผ่านไปตั้งแต่ " 17 พ.ย. 1858 :)
RonJohn

ปี 30k คือ ... ต่ำอย่างน่าประหลาดใจ
John Dvorak

2
@DonaldDuck blogs.msdn.microsoft.com/oldnewthing/20090306-00/?p=18913และประมาณ 1,600 คนยังคงใช้ปฏิทินจูเลียนแสดงวันที่ใด ๆ ก่อนหน้านั้นมีความซับซ้อนมากขึ้น
Maciej Piechotka

16

หากคุณไม่รู้สึกไม่ดีเกี่ยวกับการคาดเดาให้ฉันเสนอคำอธิบาย และฉันไม่ได้หมายถึง "ใครบางคนตั้งค่าไร้สาระ" ซึ่งเป็นไปได้เสมอ :)

เวลา Unix มักใช้จำนวนวินาทีตั้งแต่ปี 1970 ในทางกลับกัน Windows ใช้ 1601 เป็นปีเริ่มต้น ดังนั้นถ้าเราสมมติว่า (และนั่นเป็นข้อสันนิษฐานที่ยิ่งใหญ่!) ว่าปัญหาคือการแปลงผิดระหว่างสองครั้งเราสามารถจินตนาการได้ว่าวันที่ที่ควรจะเป็นตัวแทนนั้นจริง ๆ แล้วในปี 2011 (1970 + 41) ซึ่งแปลงผิด เพื่อ 1640 (1601 + 41) แก้ไข: ที่จริงฉันทำผิดพลาดในปีเริ่มต้นของ Windows อาจเป็นไปได้ว่าเวลาการสร้างจริงเกิดขึ้นในปี 2010 หรือมีข้อผิดพลาดอื่นที่เกี่ยวข้อง

เนื่องจากปีนี้เป็นวันที่ติดตามอื่นที่เกี่ยวข้องกับไฟล์ที่เป็นปัญหาฉันคิดว่ามันเป็นคำอธิบายที่น่าเชื่อถือ :)


ดังนั้นอาจเป็นไปได้ว่าวันที่เขียนเป็น Unix แต่อ่านใน UTC?
Fredy31

Windows ใช้ 1601 ไม่ใช่ 1600
Joey

3
ปัญหาเล็กน้อยเกี่ยวกับทฤษฎีนั้น: ตามภาพหน้าจอไฟล์จะถูกสร้างขึ้น 11 วันหลังจากที่มีการเข้าถึงครั้งล่าสุด นอกจากนี้การประทับเวลาของ Windows จะนับเป็น 100 นาโนวินาทีในขณะที่เวลา UNIX เป็นวินาที
Nolonar

2
@ Joe Ugh ความผิดพลาดของฉัน นั่นทำให้พอดีมากยิ่งกว่าในแวบแรก :) ฉันคิดว่าความคิดพื้นฐานเดียวกันควรจะยังคงใช้งานได้ แต่อาจมีข้อผิดพลาดมากกว่าที่ฉันคิด หรือแน่นอนไฟล์นี้ถูกสร้างขึ้นในปี 2010 ไม่ใช่ปี 2011
Luaan

2
วินาทีระหว่าง Windows ยุคและวันที่ไฟล์แสดง / เวลา1.266.705.294 เมื่อเพิ่มเข้ากับยุค Unix สิ่งนี้ให้ผล2010-02-20 23:34:54 CESTซึ่งเป็นวันเสาร์
SQB

5

ในฐานะที่ได้รับการเขียนโดยคนอื่น ๆยุคของ Windows ที่ 1601/01/01 00:00

จำนวนวินาทีระหว่างยุคที่และ FILETIME ที่แสดงที่เป็น 1.266.705.294
หากเราเพิ่มสิ่งนั้นลงในยุค Unix เรามาถึงเวลา2010-02-20 23:34:54 CESTวันเสาร์ นี่คือประมาณหนึ่งปีก่อนวันที่เข้าถึงล่าสุดซึ่งทำให้มีความน่าเชื่อถือ ดังนั้นจึงอาจเป็นการตีความ Timestamp ของ Unix กับยุคที่ไม่ถูกต้อง


น่าแปลกที่ยุคของ. NET คือ 0001-01-01 00:00 UTC (ซึ่งเป็น 1600 ปีก่อน) ดูmsdn.microsoft.com/en-us/library/...
Nayuki

2

ตามปกติสำหรับคำถามประเภทนี้บล็อกของ Raymond Chen มีคำตอบเกี่ยวกับเรื่องนี้จาก "เหตุใดจึงเป็น Win32 ยุคเมื่อวันที่ 1 มกราคม 1601?" ผลงานตั้งแต่วันที่ 6 มีนาคม 2009:

FILETIMEโครงสร้างบันทึกเวลาในรูปแบบของช่วงเวลา 100 nanosecond ตั้งแต่วันที่ 1 มกราคม 1601 ทำไมวันนั้นได้รับการแต่งตั้ง?

ปฏิทินเกรกอเรียนทำงานในรอบ 400 ปีและ 1601 เป็นปีแรกของวัฏจักรที่มีการใช้งานในขณะที่ Windows NT ได้รับการออกแบบ มันถูกเลือกให้ทำให้คณิตศาสตร์ออกมาอย่างสวยงาม

ที่จริงฉันมีอีเมลจาก Dave Cutler ยืนยันเรื่องนี้

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.