DateTimeOffsetเป็นตัวแทนของเวลาทันที (หรือเรียกอีกอย่างว่าเวลาสัมบูรณ์ ) โดยที่ฉันหมายถึงช่วงเวลาที่เป็นสากลสำหรับทุกคน (ไม่ใช่การบัญชีสำหรับวินาทีกระโดดหรือผลกระทบความสัมพันธ์ของการขยายเวลา ) วิธีที่จะเป็นตัวแทนของเวลาทันทีก็คือกับDateTimeที่เป็น.KindDateTimeKind.Utc
สิ่งนี้แตกต่างจากเวลาในปฏิทิน (หรือเรียกอีกอย่างว่าเวลาทางแพ่ง ) ซึ่งเป็นตำแหน่งในปฏิทินของใครบางคนและมีปฏิทินที่แตกต่างกันมากมายทั่วโลก เราขอเรียกร้องเหล่านี้ปฏิทินโซนเวลา ปฏิทินเวลาเป็นตัวแทนจากDateTimeที่.Kindเป็นหรือDateTimeKind.Unspecified DateTimeKind.Localและ.Localมีความหมายเฉพาะในสถานการณ์ที่คุณมีความเข้าใจโดยนัยเกี่ยวกับตำแหน่งของคอมพิวเตอร์ที่ใช้ผลลัพธ์ (ตัวอย่างเช่นเวิร์กสเตชันของผู้ใช้)
ดังนั้นแล้วทำไมDateTimeOffsetแทนที่จะ UTC เราจะต้องDateTime? มันเป็นเรื่องของมุมมอง ลองใช้การเปรียบเทียบเราจะแกล้งทำเป็นช่างภาพ
ลองนึกภาพคุณกำลังยืนอยู่บนไทม์ไลน์ของปฏิทินเล็งกล้องไปที่บุคคลบนไทม์ไลน์ที่วางด้านหน้าของคุณ คุณจัดเรียงกล้องของคุณตามกฎของเขตเวลาของคุณ - ซึ่งเปลี่ยนแปลงเป็นระยะเนื่องจากการปรับเวลาตามฤดูกาลหรือเนื่องจากการเปลี่ยนแปลงอื่น ๆ ตามคำนิยามทางกฎหมายของเขตเวลาของคุณ (คุณไม่มีมือที่มั่นคงกล้องจึงสั่นคลอน)
คนที่ยืนอยู่ในภาพถ่ายจะเห็นมุมที่กล้องของคุณมาจาก หากคนอื่นกำลังถ่ายรูปพวกเขาอาจมาจากมุมที่แตกต่างกัน นี่คือOffsetส่วนที่DateTimeOffsetแสดงถึง
ดังนั้นหากคุณติดป้ายกำกับกล้อง "เวลาตะวันออก" บางครั้งคุณก็ชี้จาก -5 และบางครั้งคุณก็ชี้จาก -4 มีกล้องอยู่ทั่วทุกมุมโลกสิ่งต่าง ๆ ที่มีป้ายกำกับและทั้งหมดชี้ไปที่ไทม์ไลน์ทันทีเดียวกันจากมุมที่แตกต่างกัน บางคนอยู่ติดกับ (หรือด้านบน) ดังนั้นเพียงแค่รู้ว่าออฟเซ็ตไม่เพียงพอที่จะกำหนดเขตเวลาที่เกี่ยวข้องกับเวลา
แล้ว UTC ล่ะ มันเป็นกล้องตัวเดียวที่รับประกันได้ว่าจะมีมือที่มั่นคง มันอยู่บนขาตั้งกล้องแล้วยึดติดกับพื้นอย่างมั่นคง มันจะไม่ไปไหน เราเรียกมุมของมันว่าค่าออฟเซ็ตเป็นศูนย์

ดังนั้น - อุปมานี้บอกอะไรเรา มันมีแนวทางง่ายๆ
DateTimeหากคุณกำลังเป็นตัวแทนของเวลาเมื่อเทียบกับบางสถานที่โดยเฉพาะอย่างยิ่งเป็นตัวแทนในเวลาปฏิทินด้วย เพียงให้แน่ใจว่าคุณไม่ได้สับสนกับปฏิทินอื่น Unspecifiedควรเป็นข้อสมมุติของคุณ จะเป็นประโยชน์เฉพาะที่มาจากLocal DateTime.Nowตัวอย่างเช่นผมอาจได้รับDateTime.Nowและบันทึกไว้ในฐานข้อมูล - Unspecifiedแต่เมื่อฉันเอามันผมต้องคิดว่ามันเป็น ฉันไม่สามารถเชื่อถือได้ว่าปฏิทินในพื้นที่ของฉันเป็นปฏิทินเดียวกับที่เคยใช้มา
หากคุณต้องมั่นใจในช่วงเวลาหนึ่งเสมอตรวจสอบให้แน่ใจว่าคุณได้แสดงเวลาทันที ใช้DateTimeOffsetเพื่อบังคับใช้หรือใช้ UTC DateTimeตามแบบแผน
หากคุณต้องการติดตามช่วงเวลาทันที แต่คุณต้องการทราบว่า "ผู้ใช้คิดว่าเวลาใดในปฏิทินท้องถิ่นของพวกเขา" - แล้วคุณจะต้องDateTimeOffsetใช้ สิ่งนี้สำคัญมากสำหรับระบบบอกเวลา - ทั้งเรื่องของเทคนิคและข้อกฎหมาย
หากคุณต้องการแก้ไขการบันทึกก่อนหน้านี้DateTimeOffset- คุณไม่มีข้อมูลเพียงพอในออฟเซ็ตเพียงอย่างเดียวเพื่อให้แน่ใจว่าออฟเซ็ตใหม่ยังคงเกี่ยวข้องกับผู้ใช้ คุณต้องยังเก็บระบุเขต (คิดว่า - ฉันต้องมีชื่อของกล้องว่าเพื่อให้สามารถถ่ายภาพใหม่แม้ว่าตำแหน่งที่มีการเปลี่ยนแปลง)
มันควรที่จะชี้ให้เห็นว่าNoda TimeมีการเรียกZonedDateTimeสิ่งนี้ในขณะที่. Net base class library ไม่มีอะไรคล้ายกัน คุณจะต้องเก็บทั้งค่าDateTimeOffsetและTimeZoneInfo.Idค่า
ในบางครั้งคุณจะต้องการแสดงเวลาปฏิทินที่อยู่ในท้องถิ่นเป็น "ผู้ที่กำลังมองหา" ตัวอย่างเช่นเมื่อนิยามความหมายของวันนี้ วันนี้เป็นเที่ยงคืนถึงเที่ยงคืนเสมอ แต่สิ่งเหล่านี้แสดงถึงช่วงเวลาที่ทับซ้อนกันเกือบไม่มีที่สิ้นสุดบนไทม์ไลน์ทันที (ในทางปฏิบัติเรามีเขตเวลาจำนวน จำกัด แต่คุณสามารถแสดงการหักล้างเพื่อขีดฆ่า) ดังนั้นในสถานการณ์เหล่านี้ตรวจสอบให้แน่ใจว่าคุณเข้าใจวิธี จำกัด "ผู้ถามหรือไม่" ถามถึงเขตเวลาเดียวหรือจัดการกับการแปลพวกเขากลับไปที่เวลาทันทีตามความเหมาะสม
ต่อไปนี้เป็นบิตเล็ก ๆ น้อย ๆ เกี่ยวกับการDateTimeOffsetสำรองข้อมูลการเปรียบเทียบนี้และเคล็ดลับในการทำให้มันตรง:
หากคุณเปรียบเทียบสองDateTimeOffsetค่าพวกเขาจะถูกทำให้เป็นมาตรฐานแรกเป็นออฟเซ็ตก่อนที่จะเปรียบเทียบ ในคำอื่น ๆ2012-01-01T00:00:00+00:00และ2012-01-01T02:00:00+02:00อ้างถึงช่วงเวลาทันทีเดียวกันและจึงเทียบเท่า
ถ้าคุณกำลังทำทดสอบหน่วยใดและจะต้องมีบางอย่างของการชดเชยการทดสอบทั้งDateTimeOffsetคุ้มค่าและ.Offsetสถานที่ให้บริการแยกต่างหาก
มีการแปลงโดยนัยทางเดียวที่สร้างไว้ภายใน. NET Framework ที่ให้คุณส่งผ่านDateTimeไปยังDateTimeOffsetพารามิเตอร์หรือตัวแปรใด ๆ เมื่อทำเช่นนั้นเรื่อง ถ้าคุณผ่านชนิด UTC ก็จะดำเนินการด้วยศูนย์ชดเชย แต่ถ้าคุณผ่านการอย่างใดอย่างหนึ่งหรือก็จะถือว่าเป็นท้องถิ่น โดยพื้นฐานแล้วกรอบบอกว่า "เอาล่ะคุณขอให้ฉันแปลงเวลาของปฏิทินเป็นเวลาทันที แต่ฉันก็ไม่รู้ว่ามันมาจากไหนดังนั้นฉันแค่จะใช้ปฏิทินท้องถิ่น" นี่เป็น gotcha ขนาดใหญ่ถ้าคุณโหลดไฟล์ที่ไม่ระบุในคอมพิวเตอร์ด้วยเขตเวลาอื่น (IMHO - นั่นควรจะเป็นข้อยกเว้น - แต่ไม่เป็นเช่นนั้น).Kind.Local.UnspecifiedDateTime
เสียบไร้ยางอาย:
หลายคนแบ่งปันกับฉันว่าพวกเขาพบว่าการเปรียบเทียบนี้มีค่ามากดังนั้นฉันจึงรวมมันไว้ในหลักสูตร Pluralsight พื้นฐานวันที่และเวลาของฉัน คุณจะพบคำแนะนำทีละขั้นตอนของการเปรียบเทียบกล้องในโมดูลที่สอง "บริบทเนื้อหา" ในคลิปชื่อ "ปฏิทินเวลาเทียบกับเวลาทันที"