DateTimeOffset
bir 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, DateTime
nerede .Kind
olduğ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, DateTime
nerede .Kind
olduğu DateTimeKind.Unspecified
veya ile temsil edilir DateTimeKind.Local
. Ve .Local
yalnı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 DateTimeOffset
bir 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 Offset
parç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. Unspecified
varsayımınız olmalı. Local
sadece yararlı geliyor DateTime.Now
. Örneğin, DateTime.Now
bir 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. DateTimeOffset
Zorlamak için kullanın veya DateTime
kurallara 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 DateTimeOffset
gerekirse, 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 DateTimeOffset
bir TimeZoneInfo.Id
değ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 DateTimeOffset
bu benzetmeyi yedekleyen birkaç küçük parça ve düz tutmak için bazı ipuçları:
İki DateTimeOffset
değ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:00
ve 2012-01-01T02:00:00+02:00
aynı 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 .
DateTime
Herhangi bir DateTimeOffset
parametre 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
.Unspecified
DateTime
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.