DateTimeOffsetbir temsilidir anlık zamanda (aynı zamanda mutlak zaman ). Bununla, herkes için evrensel olan bir anı kastediyorum ( artık saniye veya zaman genişlemesinin göreceli etkilerini hesaba katmamak ). Anlık zamanı temsil etmenin bir başka yolu, DateTimenerede .Kindolduğudur DateTimeKind.Utc.
Bu, birinin takviminde bir konum olan takvim saatinden ( sivil saat olarak da bilinir ) farklıdır ve dünyanın her yerinde birçok farklı takvim vardır. Bu takvimlere zaman dilimi diyoruz . Takvim süresi, DateTimenerede .Kindolduğu DateTimeKind.Unspecifiedveya ile temsil edilir DateTimeKind.Local. Ve .Localyalnızca sonucu kullanan bilgisayarın nerede konumlandığına dair zımni bir anlayışa sahip olduğunuz senaryolarda anlamlıdır. (Örneğin, bir kullanıcının iş istasyonu)
Öyleyse, neden DateTimeOffsetbir UTC yerine DateTime? Her şey perspektifle ilgili. Bir benzetme kullanalım - fotoğrafçı gibi davranacağız.
Bir takvim zaman çizelgesinde durduğunuzu, önünüzde ortaya çıkan anlık zaman çizelgesindeki bir kişiye kamerayı işaret ettiğinizi düşünün. Kameranızı saat diliminizin kurallarına göre sıralarsınız - gün ışığından yararlanma saati veya saat diliminizin yasal tanımındaki diğer değişiklikler nedeniyle düzenli olarak değişir. (Sabit bir eliniz yok, bu yüzden kameranız titriyor.)
Fotoğrafta duran kişi, kameranızın geldiği açıyı görür. Başkaları fotoğraf çekiyorsa, farklı açılardan olabilirler. Temsilin Offsetparçası budur DateTimeOffset.
Kameranızı "Doğu Saati" olarak etiketlerseniz, bazen -5'i, bazen de -4'ü işaret edersiniz. Tüm dünyada farklı şeyler etiketlenmiş kameralar var ve hepsi farklı açılardan aynı anlık zaman çizgisine işaret ediyor. Bazıları birbirinin hemen yanında (veya üstünde), bu yüzden ofseti bilmek zamanın hangi zaman dilimiyle ilişkili olduğunu belirlemek için yeterli değil.
Peki ya UTC? Sabit bir ele sahip olması garanti edilen tek kamera. Bir tripod üzerinde, yere sıkıca tutturulmuş. Hiçbir yere gitmiyor. Perspektif açısına sıfır ofseti diyoruz.

Peki - bu benzetme bize ne anlatıyor? Bazı sezgisel yönergeler sağlar.
Özellikle bir yere göre zamanı temsil ediyorsanız, bunu takvim zamanında a ile temsil edin DateTime. Sadece bir takvimi başka bir takvimle karıştırmamaya dikkat edin. Unspecifiedvarsayımınız olmalı. Localsadece yararlı geliyor DateTime.Now. Örneğin, DateTime.Nowbir veritabanına alıp kaydedebilirim - ancak aldığımda bunun olduğunu varsaymalıyım Unspecified. Yerel takvimimin ilk alındığı takvim olduğuna güvenemiyorum.
Andan her zaman emin olmanız gerekiyorsa, anlık zamanı temsil ettiğinizden emin olun. DateTimeOffsetZorlamak için kullanın veya DateTimekurallara göre UTC kullanın .
Anlık bir anı izlemeniz gerekiyorsa, ancak "Kullanıcı yerel takviminde saatin kaç olduğunu düşündü?" - o zaman gerekir bir kullanın DateTimeOffset. Bu, zaman işleyişi sistemleri için çok önemlidir - hem teknik hem de yasal kaygılar için.
Önceden kaydedilmiş bir değişikliği değiştirmeniz DateTimeOffsetgerekirse, yeni ofseti hala kullanıcı için uygun olduğundan emin olmak için yalnızca ofsette yeterli bilgiye sahip değilsiniz. Sen gerekir ayrıca bir zaman dilimi tanımlayıcı saklamak (düşünürsek - pozisyon değişmiş olsa bile yeni bir resim alabilir bu yüzden bu kameranın adı lazım).
Ayrıca, Noda Time'ın bunun için bir temsili olduğuna dikkat edilmelidir ZonedDateTime, ancak .Net temel sınıf kütüphanesinde benzer bir şey yoktur. Hem a hem de DateTimeOffsetbir TimeZoneInfo.Iddeğer depolamanız gerekir .
Bazen, "kim bakarsa" yerel olan bir takvim süresini temsil etmek istersiniz. Örneğin, bugün ne anlama geldiğini tanımlarken . Bugün her zaman gece yarısından gece yarısına kadardır, ancak bunlar anlık zaman çizelgesinde sonsuz sayıda örtüşen aralığı temsil eder. (Uygulamada sınırlı sayıda zaman dilimimiz var, ancak ofsetleri kene kadar ifade edebilirsiniz) Bu gibi durumlarda, "kim soruyor?" tek bir zaman dilimine yöneltiniz veya bunları uygun şekilde anında zamana çevirmekle ilgileniniz.
İşte DateTimeOffsetbu benzetmeyi yedekleyen birkaç küçük parça ve düz tutmak için bazı ipuçları:
İki DateTimeOffsetdeğeri karşılaştırırsanız , karşılaştırma yapmadan önce bunlar sıfır ofsete normalleştirilir. Başka bir deyişle, 2012-01-01T00:00:00+00:00ve 2012-01-01T02:00:00+02:00aynı anlık anı ifade eder ve bu nedenle eşdeğerdir.
Herhangi bir birim testi yapıyorsanız ve ofsetten emin olmanız gerekiyorsa, hemDateTimeOffset değeri hem de .Offsetözelliği ayrı ayrı test edin .
DateTimeHerhangi bir DateTimeOffsetparametre veya değişkene geçmenizi sağlayan .Net çerçevesine yerleşik tek yönlü bir örtülü dönüştürme vardır . Bunu yaparken, önemli . Bir UTC türünü geçerseniz, sıfır ofseti ile taşınır, ancak ikisinden birini geçerseniz veya yerel olduğunu varsayar . Çerçeve temelde, "Peki, takvim zamanını anlık zamana dönüştürmemi istediniz, ancak bunun nereden geldiğine dair hiçbir fikrim yok, bu yüzden sadece yerel takvimi kullanacağım." Farklı bir saat dilimine sahip bir bilgisayara belirtilmemişse, bu çok büyük bir sorun. (IMHO - bu bir istisna atmalı - ama değil.).Kind.Local.UnspecifiedDateTime
Utanmaz Fiş:
Birçok kişi bu benzetmeyi son derece değerli bulduklarını benimle paylaştı, bu yüzden bunu Çoğul Görüş dersim olan Date and Time Fundamentals'a dahil ettim . İkinci modül olan "Bağlam Önemlidir" bölümünde, "Takvim Süresi ve Anlık Zaman" başlıklı klipte kamera benzetmesinin adım adım izlenmesini bulacaksınız.