มี "ค่าเวลา" คงที่หรือไม่?


12

สำหรับบางระบบจะใช้ค่าเวลา 9999-12-31 เป็น "จุดสิ้นสุดเวลา" เป็นเวลาสิ้นสุดของเวลาที่คอมพิวเตอร์สามารถคำนวณได้ แต่ถ้ามันเปลี่ยนไปล่ะ? การกำหนดเวลานี้เป็นตัวแปรบิวอินจะดีกว่าหรือไม่

ใน C และภาษาการเขียนโปรแกรมอื่น ๆ มักจะมีตัวแปรเช่นMAX_INTหรือคล้ายกันเพื่อให้ได้ค่ามากที่สุดที่เป็นจำนวนเต็ม เหตุใดจึงไม่มีฟังก์ชั่นที่คล้ายกันสำหรับMAX_TIMEเช่นตั้งค่าตัวแปรเป็น "หมดเวลา" ซึ่งสำหรับหลาย ๆ ระบบมักจะเป็น 9999-12-31 เพื่อหลีกเลี่ยงปัญหาการเข้ารหัสผิดปี (9999) ระบบเหล่านี้สามารถแนะนำตัวแปรสำหรับ "หมดเวลา" หรือไม่?

** ตัวอย่างจริง **

End of validity date: 31/12/9999.(เอกสารอย่างเป็นทางการมีการระบุไว้เช่นนี้) Blogger ต้องการเขียนหน้าเว็บที่อยู่ด้านบนสุดเสมอหน้าต้อนรับ ดังนั้นจึงมีการกำหนดวันที่ในอนาคตให้มากที่สุด:

3000? ใช่หน้าต้อนรับที่คุณกำลังเผชิญถูกโพสต์เมื่อวันที่ 1 มกราคม 3000 ดังนั้นหน้านี้จะถูกเก็บไว้ที่ด้านบนของบล็อกตลอดไป =) มันโพสต์จริง ๆ แล้วในวันที่ 31 สิงหาคม 2550


6
ทำไม? ดูเหมือนว่าปัญหาที่สามารถแก้ไขได้โดยการใช้อัลกอริทึมหรือโครงสร้างข้อมูลที่ถูกต้อง
ร่าเริง

16
ผมคิดว่าคนส่วนใหญ่ไม่กังวลมากเกี่ยวกับปัญหา Y10K ยัง :-) โดยเฉพาะอย่างยิ่งก่อนที่เราจะผูกพันที่จะมีปัญหา Y2038และอาจจะคู่มากขึ้น ...
PéterTörök

2
@ Thorbjörnใช่แล้วระบบการถ่ายทอดสดส่วนใหญ่อาจถูกย้ายไปแล้ว แต่อาจจะยังมีเป็นจำนวนเงินที่ล้ำค่าปัจจุบันระบบเก่าที่ฝังตัวฐานข้อมูลเดิมไฟล์ในรูปแบบไฟล์ที่ล้าสมัย ฯลฯ
PéterTörök

14
ฉันคิดว่าปฏิทินมายามีค่าคงที่ "end of time" = 2012-12-21 ;-)
nikie

3
ไม่มีใครรู้ว่าเมื่อไหร่ "จะหมดเวลา"
Tulains Córdova

คำตอบ:


47

ถามตัวเองว่าทำไมคุณถึงต้องการตัวแปรในตอนแรก

เป็นไปได้มากว่าคุณกำลังโกหกข้อมูลของคุณ: เมื่อใดก็ตามที่คุณต้องการตัวแปร "หมดเวลา" คุณจะไม่อ้างอิงถึงเวลาสิ้นสุดจริง ค่อนข้างคุณกำลังแสดงสิ่งต่าง ๆ เช่น "ไม่มีขอบเขตบนสำหรับวันนี้", "กิจกรรมนี้ดำเนินต่อไปเรื่อย ๆ " หรือคล้ายกัน

วิธีแก้ปัญหาที่ถูกต้องนั้นคือการแสดงเจตนาเหล่านี้โดยตรงแทนที่จะอาศัยค่าเวทย์มนตร์: ใช้ประเภทวันที่nullไม่มีค่า( ระบุว่า "ไม่มีชุดวันที่สิ้นสุด") เพิ่มเขตข้อมูลบูลีน "ไม่ จำกัด " ใช้ตัวห่อ polymorphic (ซึ่งสามารถ เป็นวันที่จริงหรือค่า "ไม่ จำกัด " พิเศษ) หรือสิ่งที่ภาษาการเขียนโปรแกรมของคุณมีให้

แน่นอนว่าวิธีแก้ปัญหาที่ถูกต้องนั้นไม่ได้เป็นไปได้เสมอดังนั้นคุณอาจต้องใช้เวทย์มนตร์ท้ายที่สุด แต่เมื่อคุณทำคุณต้องตัดสินใจเลือกค่าที่เหมาะสมในแต่ละกรณีเพราะวันที่ใดที่ทำและไม่ ความสมเหตุสมผลนั้นขึ้นอยู่กับโดเมนที่คุณกำลังสร้างโมเดล - ถ้าคุณเก็บบันทึกการประทับเวลา 01/01/2999 เป็น "การสิ้นสุดเวลา" ที่สมเหตุสมผล โอกาสที่แอปพลิเคชันของคุณยังคงถูกใช้งานมาเกือบ 1,000 ปีจากนี้คือฉันจะนับว่าเป็นศูนย์ ข้อควรพิจารณาที่คล้ายกันคือไปที่แอปพลิเคชันปฏิทิน แต่ถ้าซอฟต์แวร์ของคุณจัดการกับข้อมูลทางวิทยาศาสตร์บอกว่าการคาดการณ์ระยะยาวเกี่ยวกับสภาพอากาศของโลกจะเป็นอย่างไร สิ่งเหล่านั้นอาจต้องการมองอนาคตเป็นพัน ๆ ปี หรือก้าวไปอีกขั้นหนึ่ง ดาราศาสตร์เป็นสนามที่ปกติสมบูรณ์แบบที่จะให้เหตุผลในช่วงเวลาที่มีขนาดใหญ่มากตามลำดับพันล้านปี ทั้งในเส้นทางและในอนาคต สำหรับสิ่งเหล่านั้น 01/01/2999 เป็นค่าสูงสุดที่ไร้สาระโดยพลการอย่างสมบูรณ์ OTOH ระบบปฏิทินที่สามารถจัดการเวลาได้ถึงสิบล้านล้านปีในอนาคตนั้นแทบจะใช้งานไม่ได้กับระบบติดตามการนัดหมายของทันตแพทย์หากเพียงเพราะความจุ

กล่าวอีกนัยหนึ่งไม่มีทางเลือกที่ดีที่สุดสำหรับค่าที่ผิดและโดยพลการตามคำนิยามที่จะเริ่มต้นด้วย นี่คือเหตุผลว่าทำไมจึงเป็นเรื่องแปลกที่จะเห็นหนึ่งที่กำหนดไว้ในภาษาการเขียนโปรแกรมใด ๆ ; ผู้ที่มักจะไม่ตั้งชื่อมันว่า "เวลาสิ้นสุด" แต่เป็นสิ่งที่ชอบDATE_MAX(หรือDate.MAX) และใช้มันเพื่อหมายถึง "ค่าที่ใหญ่ที่สุดที่สามารถเก็บไว้ในประเภทข้อมูลวันที่" ไม่ใช่ "จุดสิ้นสุดของเวลา" หรือ "ไปเรื่อย ๆ"


20
การใช้ค่า null เพื่อหมายถึงค่าพิเศษนั้นไม่ได้ดีไปกว่าการใช้ค่าพิเศษนั้น
Ryathal

2
@Ryathal ดีฉันคิดว่าไม่มีข้อผิดพลาด 'nullenium' ดังนั้นอย่างน้อยก็ดีกว่า ...
K.Steff

8
@Ryathal: จริง ๆ แล้วมันไม่ใช่ มีการดำเนินการหลายอย่างที่คุณสามารถทำได้กับจำนวนเวทย์มนตร์ที่คุณไม่สามารถทำได้โดยไม่มีค่าใช้จ่าย
Pieter B

21
@Ryathal - nullในกรณีนี้ไม่ได้ใช้เป็นค่าพิเศษมันถูกใช้เป็นความหมายที่ถูกต้องnullซึ่งก็คือ "หายไป" ดังนั้นหากสาขาของคุณExpiryDateซึ่งถูกต้องมากขึ้น: null(หมายถึงไม่มีวันหมดอายุ) หรือEND_OF_TIME(ซึ่งไม่มีอยู่เท่าที่เรารู้) ชัดเจนnullหรือNoValueสิ่งที่คล้ายกันเป็นทางออกที่ดีกว่า
Scott Whitlock

3
@ jwenting - พวกเขาไม่แยกความแตกต่างเพราะไม่มี เป็นโมฆะหมายความว่ามันไม่ได้มีอยู่หรือในแง่มนุษย์มากกว่าค่าที่ไม่ได้กำหนดไว้
Ramhound

17

ในฐานะที่เป็นอุตสาหกรรมเราได้รับการกล่าวขานในระยะสั้นและเป็นที่รู้จักโดยพลการในการแสวงหาการช่วยชีวิตไม่กี่ไบต์เช่น

  • 31 ธันวาคม 99
  • 19 มกราคม 2581
  • T + 50 ปีที่ผ่านมาเมื่อหวังว่าทุกระบบที่ฉันเข้ามาเกี่ยวข้องจะหมดสภาพหรือถูกแทนที่ (หรือฉันตายแล้วแต่ว่าอย่างใดจะถึงก่อน)

IMHO ทางออกที่ดีที่สุดคือให้อยู่ในระดับที่เหมาะสมในระดับที่เป็นนามธรรมของ 'วันที่สูงสุด' และหวังว่าโซลูชันทั่วไปจะจัดการปัญหานี้ได้ก่อนถึงเวลา

เช่นใน .NET, DateTime.MaxValue23:59:59.9999999, December 31, 9999, exactly one 100-nanosecond tick before 00:00:00, January 1, 10000เป็นพล ดังนั้นหากสมมติฐานของฉันเกี่ยวกับอายุการใช้งานของฉันเป็นเท็จและปีที่ 10,000 มาถึงฉันหวังว่าการคอมไพล์แอพของฉันด้วยเฟรมเวิร์กเวอร์ชันที่ใหม่กว่าจะขยายออกไปDateTime.MaxValue(เช่นโดยการเปลี่ยนประเภทพื้นฐาน) เป็นค่านิยมใหม่ และเตะปัญหาไปตามถนนอีกสองสามพันปี

แก้ไข

(การตอกย้ำถึงจุด tdammers 'ที่ไม่ใช่การปลอมแปลงวันที่เทียมว่าเป็นการถูกต้องมากกว่าที่จะเน้นข้อเท็จจริงที่ชัดเจนไปยังผู้บริโภคว่าเราไม่มีวันที่สิ้นสุด)

ทางเลือกในการใช้nullงานซึ่งมีผลกระทบด้านลบของการใช้งานร่วมกับประเภทอ้างอิงใด ๆ (รวมถึง. Net Nullable`) ซึ่งอาจทำให้เกิดปัญหา NRE ในผู้บริโภคที่ลืมตรวจสอบในภาษา FP มันเป็นเรื่องธรรมดาที่จะใช้ตัวเลือกหรือบางทีพิมพ์เสื้อคลุมรอบค่าซึ่งอาจหรืออาจจะไม่ถูกส่งกลับ

รหัสหลอก:

Option<DateTime> LeaseExpiryDate(Home rental) 
{
    if (... expiry date can be determined ...)
       return Some(rental.ExpiryDate);
    else
       return None;
}

ประโยชน์ของการทำเช่นนี้คือมันบังคับให้ผู้บริโภคให้เหตุผลมากกว่าทั้งสองกรณี การจับคู่รูปแบบเป็นเรื่องธรรมดาที่นี่:

LeaseExpiryDate(myHome) match {
     case Some(expiryDate) => "Expired"
     case None => "No Expiry"
}

ดุจ ฉันตาบอด ไม่เป็นไร.
ott--

สักวันบางที เราจะมีWilliam Kahanสำหรับวันและเวลา เราจะมีสิ่งต่าง ๆ เช่นการประทับเวลาที่เป็นบวกและไม่ จำกัด ในเชิงลบ " NaT" ค่าฯลฯ
Ross Patterson

4
ไม่สามารถช่วยได้ แต่ได้รับการเตือนเกี่ยวกับสิ่งนี้: exit109.com/~ghealton/y2k/y2k_humor/Cobol.html
Julia Hayward

7

คุณอาจต้องการที่มีตัวแปรใหญ่ที่ไม่มีที่สิ้นสุดalgebraic data type dateจากนั้นกำหนดการเปรียบเทียบซึ่งinfiniteตัวแปรจะใหญ่กว่าตัวอื่นdateเสมอ

ตัวอย่างใน Scala:

sealed abstract class SmartTime extends Ordered[SmartTime] { x =>
        def compare(y: SmartTime) = {
                x match {
                        case InfiniteFuture => 1
                        case InfinitePast => -1
                        case ConcreteTime(x) =>
                                y match {
                                        case InfiniteFuture => -1
                                        case InfinitePast => 1
                                        case ConcreteTime(y) => x compare y
                                }
                }
        }
}
case class ConcreteTime(t: Long) extends SmartTime
case object InfiniteFuture extends SmartTime
case object InfinitePast extends SmartTime

http://ideone.com/K5Kuk


อ้างรหัสในคำตอบของคุณสำหรับลูกหลาน
มรณะ

2

เก็บเวลาของคุณเป็น 64 บิต IEE754 +INFแม่นยำสองลอยจำนวนจุดและคุณสามารถใช้ อย่าใช้ความแม่นยำเดียวที่ถูกต้องเพียง 7 หลักซึ่งค่อนข้างต่ำสำหรับวันที่


1

Cocoa / Objective-C มีวิธีการในโรงงาน [NSDate distantPast] และ [NSDate distantFuture] ที่แสดงถึงประเภทของสิ่งที่คุณอ้างถึงอย่างแท้จริง

ค่าที่ส่งคืนโดยการใช้งานปัจจุบันเป็นค่าคงที่ซึ่งเป็นค่าประมาณ 0 AD และ 4000 AD แม้ว่าค่าเหล่านี้จะไม่รับประกันหรือรับรองเอกสาร


0

โดยทั่วไปจะไม่มีค่าดังกล่าวเพราะจะไม่เป็นประโยชน์ในการสร้างภาษา

MAX_INTและมันก็เป็นวัตถุประสงค์เดียวกัน พวกเขาสามารถใช้ในรหัสของคุณเพื่อตรวจสอบกับล้น สิ่งนี้มีประโยชน์ถ้าคุณกำลังสร้างและจัดการวัตถุข้อมูลขนาดใหญ่ในอาร์เรย์เวกเตอร์หรืออะไรก็ตาม นอกจากนี้ยังเป็นค่าเฉพาะแพลตฟอร์มที่เป็นธรรม

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


0

ในโครงการหนึ่งที่เราทำเรามีสถานการณ์ที่การปรับขนาดฐานข้อมูลบางอย่างในลักษณะที่จะไม่ยั่งยืนหลังจาก 30 ปีของการใช้ซอฟต์แวร์ เมื่อลูกค้าถามวิศวกรหลักของเราในเวลานั้น: "เอาละเราจะทำอะไรหลังจากใช้ซอฟต์แวร์มา 30 ปี" วิศวกรหลักของเราเจ๋งเหมือนแตงกวาตอบด้วยยักไหล่: "เราจะไปและดื่มเบียร์!"

จุดคือเพียงใช้วันที่ที่ไกลพอในอนาคต โอกาสที่ซอฟต์แวร์ของคุณจะได้รับการอัพเกรดหรือแทนที่ในเวลานั้น :)

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