รับเขตเวลาจาก DateTime


103

. Net DateTime มีข้อมูลเกี่ยวกับเขตเวลาที่สร้างขึ้นหรือไม่

ฉันมีไลบรารีที่แยกวิเคราะห์ DateTime จากรูปแบบที่มี "+ zz" ต่อท้ายและในขณะที่มันแยกวิเคราะห์อย่างถูกต้องและปรับเวลาท้องถิ่นฉันจำเป็นต้องทราบว่าเขตเวลาเฉพาะคืออะไรจากออบเจ็กต์ DateTime

เป็นไปได้หรือไม่ สิ่งที่ฉันเห็นคือ DateTime.Kind ซึ่งระบุว่าเวลาเป็นเวลาท้องถิ่นหรือ UTC


ดูหมายเหตุเกี่ยวกับDateTime.Parse เอกสารสำหรับการจัดการโซนเวลาและ DateTimeStyles แต่ไม่สิ่งที่คุณต้องการเป็นไปไม่ได้จริงๆ
โยโย่

คำตอบ:


136

DateTime ไม่มีข้อมูลเขตเวลาจริง มันอาจจะทราบว่ามัน UTC หรือท้องถิ่น แต่ไม่ใช่สิ่งที่ท้องถิ่นจริงๆหมายถึง

DateTimeOffset ค่อนข้างดีกว่าซึ่งโดยพื้นฐานแล้วเป็นเวลา UTC และเป็นค่าชดเชย อย่างไรก็ตามนั่นยังไม่เพียงพอที่จะกำหนดเขตเวลาได้เนื่องจากเขตเวลาที่แตกต่างกันจำนวนมากสามารถมีค่าชดเชยเดียวกัน ณ จุดใดช่วงเวลาหนึ่ง ดูเหมือนว่าอาจจะดีพอสำหรับคุณเนื่องจากสิ่งที่คุณต้องดำเนินการเมื่อแยกวิเคราะห์วันที่ / เวลาเป็นค่าชดเชย

การรองรับโซนเวลา ณ . NET 3.5 นั้นดีกว่าเดิมมาก แต่ฉันอยากเห็น "ZonedDateTime" มาตรฐานหรืออะไรทำนองนั้น - เวลา UTC และเขตเวลาจริง สร้างเองได้ง่าย แต่คงจะดีหากได้เห็นในไลบรารีมาตรฐาน

แก้ไข: เกือบสี่ปีต่อมาฉันขอแนะนำให้ใช้Noda Timeซึ่งมีประเภทวันที่ / เวลาที่ค่อนข้างสมบูรณ์กว่า ฉันลำเอียงในฐานะผู้เขียนหลักของ Noda Time :)


2
PublicDomain projhect บน CodePlex ทำเพื่อคุณ
Cheeso

TimeZone enum ใน BCL จะดีถ้าโซนเวลาโลกคงที่และไม่เปลี่ยนแปลง
Jeff LaFay

1
@jlafay: อย่างไรก็ตามมีการเปลี่ยนแปลง - มีการเพิ่มเขตเวลาเพิ่มเติมใน Windows เมื่อปีที่แล้วเช่น
Jon Skeet

โครงการนี้ไม่ได้รับการดูแลโดยผู้เขียนอีกต่อไป publicdomain.codeplex.com ดูเหมือนว่าอันนี้อาจช่วยได้ขึ้นอยู่กับการใช้งานต้องตั้งค่าก่อนใช้งาน timezone.codeplex.com
AnneTheAgile

3
@AnneTheAgile: โดยส่วนตัวแล้วฉันแนะนำให้ใช้ห้องสมุด Noda Time ของฉันเองแน่นอน :)
Jon Skeet

36

ไม่

นักพัฒนามีหน้าที่ติดตามข้อมูลโซนเวลาที่เกี่ยวข้องกับค่า DateTime ผ่านกลไกภายนอกบางอย่าง

อ้างจากบทความดีที่นี่ ต้องอ่านสำหรับนักพัฒนา. Net ทุกคน

ดังนั้นคำแนะนำของฉันคือเขียนคลาสกระดาษห่อเล็ก ๆ ที่เหมาะกับความต้องการของคุณ



2

คุณสามารถใช้คลาสTimeZoneInfo

คลาส TimeZone จดจำเขตเวลาท้องถิ่นและสามารถแปลงเวลาระหว่างเวลาสากลเชิงพิกัด (UTC) และเวลาท้องถิ่น ออบเจ็กต์ TimeZoneInfo สามารถแสดงโซนเวลาใดก็ได้และเมธอดของคลาส TimeZoneInfo สามารถใช้เพื่อแปลงเวลาในโซนเวลาหนึ่งเป็นเวลาที่สอดคล้องกันในเขตเวลาอื่น ๆ สมาชิกของคลาส TimeZoneInfo สนับสนุนการดำเนินการต่อไปนี้:

  1. การดึงเขตเวลาที่ระบบปฏิบัติการกำหนดไว้แล้ว

  2. การระบุเขตเวลาที่พร้อมใช้งานบนระบบ

  3. การแปลงเวลาระหว่างเขตเวลาต่างๆ

  4. การสร้างเขตเวลาใหม่ที่ไม่ได้กำหนดโดยระบบปฏิบัติการ

    การจัดลำดับโซนเวลาสำหรับการดึงข้อมูลในภายหลัง


1
... แต่เมื่อพิจารณา DateTime แล้วยังไม่มีวิธีใช้ TimeZoneInfo เพื่อกำหนด TimeZone ของ DateTime ตามความรู้ของฉัน
Remi Despres-Smyth

@ RemiDespres-Smyth ฉันเพิ่งเก็บ TimeZoneInfo พร้อมกับ DateTime ใน 1 คลาส
Konrad


0

โดยทั่วไปวิธีปฏิบัติคือการส่งผ่านข้อมูลเป็น DateTime ด้วย "เขตเวลา" ของ UTC จากนั้นส่งผ่านวัตถุ TimeZoneInfo และเมื่อคุณพร้อมที่จะแสดงข้อมูลคุณใช้วัตถุ TimeZoneInfo เพื่อแปลง UTC DateTime

ตัวเลือกอื่นคือการตั้งค่า DateTime ด้วยเขตเวลาปัจจุบันจากนั้นตรวจสอบให้แน่ใจว่า "เขตเวลา" ไม่รู้จักสำหรับวัตถุ DateTime จากนั้นตรวจสอบให้แน่ใจว่า DateTime ถูกส่งผ่านอีกครั้งด้วย TimeZoneInfo ที่ระบุ TimeZone ของ DateTime ที่ผ่านไป

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


0

DateTime ไม่ทราบการชดเชยเขตเวลา ไม่มีวิธีการในตัวในการคืนค่าออฟเซ็ตหรือชื่อเขตเวลา (เช่น EAT, CEST, EST เป็นต้น)

เช่นเดียวกับที่ผู้อื่นแนะนำคุณสามารถแปลงวันที่ของคุณเป็น UTC:

DateTime localtime = new DateTime.Now;
var utctime = localtime.ToUniversalTime();

จากนั้นคำนวณเฉพาะความแตกต่าง:

TimeSpan difference = localtime - utctime;

นอกจากนี้คุณสามารถแปลงครั้งหนึ่งเป็นอีกครั้งได้โดยใช้ DateTimeOffset:

DateTimeOffset targetTime = DateTimeOffset.Now.ToOffset(new TimeSpan(5, 30, 0));

แต่นี่เป็นการบีบอัดแบบสูญเสีย - การชดเชยเพียงอย่างเดียวไม่สามารถบอกคุณได้ว่าเป็นเขตเวลาใดเนื่องจากสองประเทศที่แตกต่างกันอาจอยู่ในเขตเวลาที่ต่างกันและมีเวลาเดียวกันในบางส่วนของปีเท่านั้น (เช่นแอฟริกาใต้และยุโรป) นอกจากนี้โปรดทราบว่าอาจมีการใช้เวลาออมแสงในฤดูร้อนในวันที่ต่างกัน (EST เทียบกับ CET - ต่างกัน 3 สัปดาห์)

คุณสามารถรับชื่อโซนเวลาของระบบท้องถิ่นของคุณโดยใช้คลาส TimeZoneInfo:

TimeZoneInfo localZone = TimeZoneInfo.Local;
localZone.IsDaylightSavingTime(localtime) ? localZone.DaylightName : localZone.StandardName

ฉันเห็นด้วยกับ Gerrie Schenck โปรดอ่านบทความที่เขาแนะนำ

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