ฉันสงสัยว่าหลักการของคุณสมบัติทั้งสองนี้ทำงานอย่างไร ฉันรู้ว่าตัวที่สองเป็นสากลและโดยทั่วไปไม่ได้จัดการกับเขตเวลา แต่ใครสามารถอธิบายรายละเอียดว่าพวกเขาทำงานอย่างไรและควรใช้อันไหนในสถานการณ์สมมติ
ฉันสงสัยว่าหลักการของคุณสมบัติทั้งสองนี้ทำงานอย่างไร ฉันรู้ว่าตัวที่สองเป็นสากลและโดยทั่วไปไม่ได้จัดการกับเขตเวลา แต่ใครสามารถอธิบายรายละเอียดว่าพวกเขาทำงานอย่างไรและควรใช้อันไหนในสถานการณ์สมมติ
คำตอบ:
DateTimeUTCNowจะบอกวันที่และเวลาให้คุณในรูปแบบ Coordinated Universal Time ซึ่งเรียกว่า Greenwich Mean Time zone - โดยทั่วไปแล้วถ้าคุณอยู่ในลอนดอนประเทศอังกฤษ แต่ไม่ใช่ในช่วงฤดูร้อน DateTime ขณะนี้ให้วันที่และเวลาเหมือนที่ปรากฏแก่บางคนในสถานที่ปัจจุบันของคุณ
ฉันขอแนะนำให้ใช้DateTime.Now
เมื่อใดก็ตามที่คุณแสดงวันที่ให้กับมนุษย์ - วิธีที่พวกเขาพอใจกับคุณค่าที่พวกเขาเห็น - เป็นสิ่งที่พวกเขาสามารถเปรียบเทียบกับสิ่งที่พวกเขาเห็นบนนาฬิกาหรือนาฬิกาได้อย่างง่ายดาย ใช้DateTime.UtcNow
เมื่อคุณต้องการจัดเก็บวันที่หรือใช้สำหรับการคำนวณในภายหลังด้วยวิธีนี้ (ในรูปแบบไคลเอนต์ - เซิร์ฟเวอร์) การคำนวณของคุณจะไม่สับสนโดยลูกค้าในเขตเวลาที่แตกต่างจากเซิร์ฟเวอร์ของคุณหรือจากกันและกัน
มันค่อนข้างง่ายจริงๆดังนั้นฉันคิดว่ามันขึ้นอยู่กับว่าผู้ชมของคุณอยู่ที่ไหนและพวกเขาอยู่ที่ไหน
หากคุณไม่ได้ใช้ Utc คุณต้องทราบเขตเวลาของบุคคลที่คุณแสดงวันที่และเวลา - มิฉะนั้นคุณจะบอกพวกเขาว่ามีบางสิ่งเกิดขึ้นในเวลา 15.00 น. ในระบบหรือเวลาเซิร์ฟเวอร์เมื่อเกิดขึ้นจริงในเวลา 17.00 น. พวกเขามีชีวิตอยู่
เราใช้ DateTime.UtcNow
เพราะเรามีผู้ชมเว็บทั่วโลกและเพราะฉันไม่ต้องการให้ผู้ใช้ทุกคนกรอกแบบฟอร์มเพื่อระบุเขตเวลาที่พวกเขาอาศัยอยู่
นอกจากนี้เรายังแสดงเวลาที่สัมพันธ์กัน (2 ชั่วโมงที่ผ่านมา 1 วันที่ผ่านมา ฯลฯ ) จนกระทั่งโพสต์มีอายุพอที่เวลานั้น "เหมือนกัน" ไม่ว่าคุณจะอยู่ที่ไหนบนโลก
ยังทราบความแตกต่างของประสิทธิภาพ DateTime.UtcNow
อยู่ที่ไหนสักแห่งเร็วกว่าประมาณ30เท่าDateTime.Now
เนื่องจากภายในDateTime.Now
มีการปรับเปลี่ยนเขตเวลาจำนวนมาก (คุณสามารถตรวจสอบได้ด้วยตัวสะท้อนแสง)
ดังนั้นอย่าใช้DateTime.Now
สำหรับการวัดเวลาสัมพัทธ์
หนึ่งในแนวคิดสำคัญที่ต้องเข้าใจใน NET เป็นว่าตอนนี้เป็นตอนนี้ทั่วทุกมุมโลกไม่ว่าสิ่งที่โซนเวลาที่คุณอยู่ในดังนั้นถ้าคุณโหลดตัวแปรที่มี. DateTime.Now
หรือDateTime.UtcNow
-. ที่ได้รับมอบหมายเป็นเหมือนของคุณ * DateTime
วัตถุรู้ว่าสิ่งที่เขตเวลาที่คุณอยู่ใน และคำนึงถึงสิ่งนั้นโดยไม่คำนึงถึงการมอบหมาย
ประโยชน์ของการใช้งานDateTime.UtcNow
มีประโยชน์เมื่อคำนวณวันที่ข้ามขอบเขตเวลาออมแสง นั่นคือในสถานที่ที่มีส่วนร่วมในการปรับเวลาตามฤดูกาลบางครั้งมี 25 ชั่วโมงตั้งแต่เที่ยงวันถึงเที่ยงในวันรุ่งขึ้นและบางครั้งมี 23 ชั่วโมงระหว่างเที่ยงและเที่ยงในวันรุ่งขึ้น หากคุณต้องการกำหนดจำนวนชั่วโมงจากเวลา A และเวลา B อย่างถูกต้องคุณจะต้องแปลแต่ละครั้งเป็นเทียบเท่า UTC ก่อนที่จะคำนวณTimeSpan
ของพวกเขาก่อนที่จะคำนวณ
นี่คือโพสต์บล็อกที่ฉันเขียนที่อธิบายเพิ่มเติมTimeSpan
และรวมถึงลิงก์ไปยังบทความ MS ที่กว้างขวางยิ่งขึ้นในหัวข้อ
* ความชัดเจน: การมอบหมายอย่างใดอย่างหนึ่งจะเก็บเวลาปัจจุบัน หากคุณต้องโหลดตัวแปรสองตัวตัวหนึ่งผ่านทางDateTime.Now()
และอีกตัวหนึ่งผ่านDateTime.UtcNow()
ความTimeSpan
แตกต่างระหว่างสองตัวนั้นจะเป็นมิลลิวินาทีไม่ใช่ชั่วโมงสมมติว่าคุณอยู่ในเขตเวลานอกเวลาจาก GMT ดังที่ระบุไว้ด้านล่างการพิมพ์String
ค่าของพวกเขาจะแสดงสตริงที่แตกต่างกัน
นี่เป็นคำถามที่ดี ฉันกำลังฟื้นฟูเพื่อให้รายละเอียดเพิ่มเติมเล็กน้อยว่า. Net ทำงานอย่างไรกับKind
ค่าที่แตกต่างกัน @Jan Zich ชี้ให้เห็นว่าจริง ๆ แล้วมันเป็นคุณสมบัติที่สำคัญอย่างยิ่งและมีการตั้งค่าที่แตกต่างกันไปขึ้นอยู่กับว่าคุณใช้Now
หรือUtcNow
หรือ
ภายในวันที่จะถูกจัดเก็บตามTicks
ที่ (ตรงข้ามกับคำตอบของ @Carl Camera) จะแตกต่างกันไปขึ้นอยู่กับว่าคุณใช้Now
หรือUtcNow
หรือ
DateTime.UtcNow
มีพฤติกรรมเหมือนภาษาอื่น ๆ มันตั้งTicks
ค่าตาม GMT อีกทั้งยังตั้งค่าKind
ให้Utc
ที่จะ
DateTime.Now
alters * Ticks
มูลค่าให้กับสิ่งที่มันจะเป็นถ้ามันเป็นเวลาของคุณในวันในเขตเวลา GMT อีกทั้งยังตั้งค่าKind
ให้Local
ที่จะ
หากคุณอยู่ช้ากว่า 6 ชั่วโมง (GMT-6) คุณจะได้รับเวลา GMT จาก 6 ชั่วโมงที่ผ่านมา .Net จะเพิกเฉยKind
และปฏิบัติต่อในเวลานี้ราวกับว่ามันเป็น 6 ชั่วโมงที่ผ่านมาแม้ว่ามันควรจะเป็น "ตอนนี้" สิ่งนี้จะทำลายได้มากขึ้นถ้าคุณสร้างDateTime
อินสแตนซ์จากนั้นเปลี่ยนเขตเวลาของคุณและลองใช้
อินสแตนซ์ DateTime ที่มีค่า 'ชนิด' แตกต่างกันเข้ากันไม่ได้
ลองดูรหัสบางส่วน ...
DateTime utc = DateTime.UtcNow;
DateTime now = DateTime.Now;
Debug.Log (utc + " " + utc.Kind); // 05/20/2015 17:19:27 Utc
Debug.Log (now + " " + now.Kind); // 05/20/2015 10:19:27 Local
Debug.Log (utc.Ticks); // 635677391678617830
Debug.Log (now.Ticks); // 635677139678617840
now = now.AddHours(1);
TimeSpan diff = utc - now;
Debug.Log (diff); // 05:59:59.9999990
Debug.Log (utc < now); // false
Debug.Log (utc == now); // false
Debug.Log (utc > now); // true
Debug.Log (utc.ToUniversalTime() < now.ToUniversalTime()); // true
Debug.Log (utc.ToUniversalTime() == now.ToUniversalTime()); // false
Debug.Log (utc.ToUniversalTime() > now.ToUniversalTime()); // false
Debug.Log (utc.ToUniversalTime() - now.ToUniversalTime()); // -01:00:00.0000010
อย่างที่คุณเห็นที่นี่ฟังก์ชั่นการเปรียบเทียบและคณิตศาสตร์ไม่ได้แปลงเป็นเวลาที่เข้ากันได้โดยอัตโนมัติ Timespan
ควรจะได้รับเกือบหนึ่งชั่วโมง แต่ก็เกือบ 6 "UTC <ตอนนี้" ควรจะได้รับจริง (ฉันยังเพิ่มชั่วโมงเพื่อให้แน่ใจว่า) แต่ก็ยังคงเป็นเท็จ
คุณยังสามารถดู 'การทำงานรอบด้าน' ซึ่งจะแปลงเป็นเวลาสากลทุกที่ Kind
ไม่เหมือนกัน
คำตอบของคำถามโดยตรงของฉันเห็นด้วยกับคำแนะนำของคำตอบที่ยอมรับเกี่ยวกับเวลาที่จะใช้แต่ละข้อ คุณควรพยายามทำงานกับDateTime
วัตถุที่มีKind=Utc
ยกเว้นระหว่าง i / o (การแสดงและการแยกวิเคราะห์) ซึ่งหมายความว่าคุณควรใช้งานเกือบตลอดเวลาDateTime.UtcNow
ยกเว้นกรณีที่คุณสร้างวัตถุเพื่อแสดงวัตถุและทิ้งมันทันที
DateTime ไม่มีความคิดว่าเขตเวลาคืออะไร มันจะถือว่าคุณอยู่ในเวลาท้องถิ่นของคุณ UtcNowหมายถึง "ลบเขตเวลาของฉันจากเวลา" เท่านั้น
หากคุณต้องการใช้วันที่ทราบเขตเวลาใช้DateTimeOffsetซึ่งแสดงวันที่ / เวลาด้วยเขตเวลา ฉันต้องเรียนรู้ว่าวิธีที่ยากลำบาก
คำตอบที่ "ง่าย" สำหรับคำถามคือ:
DateTime ขณะนี้ส่งคืนค่าDateTime ที่แสดงเวลาปัจจุบันของระบบ (ในเขตเวลาใดก็ตามที่ระบบกำลังทำงานอยู่) DateTime.KindคุณสมบัติจะDateTimeKind.Local
DateTime.UtcNowส่งคืนค่าDateTime ซึ่งเป็นตัวแทนของเวลาพิกัดสากลปัจจุบัน (aka UTC) ซึ่งจะเหมือนกันโดยไม่คำนึงถึงเขตเวลาของระบบ DateTime.KindคุณสมบัติจะDateTimeKind.Utc
นอกเหนือจากจุดที่ทำข้างต้นเล็กน้อย: โครงสร้าง DateTime ยังมีเขตข้อมูลที่รู้จักเล็กน้อยที่เรียกว่าชนิด (อย่างน้อยฉันไม่ทราบเกี่ยวกับมันเป็นเวลานาน) มันเป็นเพียงแค่การตั้งค่าสถานะที่ระบุว่าเวลาเป็นท้องถิ่นหรือ UTC; ไม่ได้ระบุออฟเซ็ตจริงจาก UTC สำหรับเวลาท้องถิ่น นอกจากความจริงที่ว่ามันแสดงให้เห็นกับสิ่งที่ตั้งใจ stuct ถูกสร้างก็ยังมีอิทธิพลต่อวิธีการที่วิธีการToUniversalTime ()และToLocalTime ()การทำงาน
สายไปงานเลี้ยงเล็กน้อย แต่ฉันพบว่าลิงก์ทั้งสอง (4guysfromrolla) มีประโยชน์มาก:
การใช้เวลาสากลเชิงพิกัด (UTC) เพื่อจัดเก็บค่าวันที่ / เวลา
คำแนะนำสำหรับการจัดเก็บและแสดงวันที่และเวลาในโซนเวลาที่ต่างกัน
DateTime.UtcNow เป็นมาตราส่วนเวลาแบบต่อเนื่องที่มีค่าเดียวในขณะที่ DateTime.Now ไม่ต่อเนื่องหรือมีค่าเดียว เหตุผลหลักคือเวลาออมแสงซึ่งไม่ได้ใช้กับ UTC ดังนั้น UTC จะไม่ข้ามไปข้างหน้าหรือย้อนกลับหนึ่งชั่วโมงในขณะที่เวลาท้องถิ่น (DateTime.Now) ทำ และเมื่อมันกระโดดไปข้างหลังค่าเวลาเดียวกันจะเกิดขึ้นสองครั้ง
DateTime.UtcNow เป็นมาตราส่วนเวลาสากลที่ไม่ใช้เวลาออมแสง UTC ไม่เคยเปลี่ยนแปลงเนื่องจาก DST
แต่ DateTime ตอนนี้ไม่ต่อเนื่องหรือมีมูลค่าเดียวเพราะจะเปลี่ยนแปลงตาม DST ซึ่งหมายถึง DateTime ขณะนี้ค่าเวลาเดียวกันอาจเกิดขึ้นสองครั้งที่ทำให้ลูกค้าอยู่ในสถานะสับสน
เมื่อคุณต้องการเวลาท้องถิ่นสำหรับเครื่องที่แอปพลิเคชันของคุณทำงาน (เช่น CEST สำหรับยุโรป) ให้ใช้ทันที หากคุณต้องการเวลาสากล - UtcNow มันเป็นเรื่องของการตั้งค่าของคุณ - อาจสร้างเว็บไซต์ท้องถิ่น / แอปพลิเคชันแบบสแตนด์อโลนที่คุณต้องการใช้เวลาที่ผู้ใช้มี - ดังนั้นได้รับผลกระทบจากการตั้งค่าเขตเวลาของเขา / เธอ - DateTime ตอนนี้
เพียงจำไว้ว่าสำหรับเว็บไซต์การตั้งค่าเขตเวลาของเซิร์ฟเวอร์ ดังนั้นหากคุณกำลังแสดงเวลาสำหรับผู้ใช้ให้เลือกเขตเวลาที่ต้องการและเปลี่ยนเวลา (เพียงบันทึกเวลา Utc ไปยังฐานข้อมูลแล้วปรับเปลี่ยน) หรือระบุ UTC หากคุณลืมที่จะทำเช่นนั้นผู้ใช้สามารถเห็นสิ่งที่ชอบ: โพสต์ 3 minuses ที่ผ่านมาแล้วเวลาในอนาคตใกล้ :)
ข้อแตกต่างใหญ่ :) คือ DateTime ขณะนี้ไม่ได้รับการสนับสนุนใน SharePoint Workflow คุณต้องใช้ DateTime.UtcNow