DateTime (UTC) ve DateTimeOffset depolama


97

Genellikle veritabanından / veritabanından okumadan / veritabanına yazmadan hemen önce DateTime dönüşümü yapan (UTC'den yerel saate ve yerel saatten UTC'ye) bir "yakalayıcım" var, böylece DateTime.Nowendişelenmeden sistem genelinde kullanabilirim (türevler ve karşılaştırmalar) saat dilimleri hakkında.

Serileştirme ve bilgisayarlar arasında veri taşıma ile ilgili olarak, tarih saati her zaman UTC olduğundan, uğraşmaya gerek yoktur.

Tarihlerimi (SQL 2008 - datetime) UTC formatında saklamaya devam etmeli miyim yoksa bunun yerine DateTimeOffset(SQL 2008 - datetimeoffset) kullanarak mı depolamalıyım ?

Veritabanındaki UTC Tarihleri ​​(tarih saat türü) çok uzun süredir çalışıyor ve biliniyor, neden değiştirilsin? Avantajları nelerdir?

Zaten gibi eşyalar haline baktım bu bir , ama ben% 100 olsa ikna değilim. Düşüncesi olan var mı?



1
Ayrıca bakınız: DateTime vs DateTimeOffset - .Net için yazılmıştır, ancak kavramsal olarak SQL için de geçerlidir.
Matt Johnson-Pint

Yanıtlar:


131

UTC'yi tek başına kullanamayacağınız çok büyük bir fark var.

  • Böyle bir senaryonuz varsa

    • Bir sunucu ve birkaç istemci (tümü coğrafi olarak farklı saat dilimlerinde )
    • İstemciler datetime bilgileriyle bazı veriler oluşturur
    • İstemciler hepsini merkezi sunucuda depolar
  • Sonra:

    • datetimeoffset, istemcinin Yerel saatini ve AYRICA UTC saatine uzaklığı depolar
    • tüm müşteriler tüm verilerin UTC saatini ve ayrıca bilginin geldiği yerdeki yerel saati bilir.
  • Fakat:

    • UTC tarih saati yalnızca UTC tarih saatini depolar , bu nedenle verilerin geldiği istemci konumundaki yerel saat hakkında bilgi sahibi olmazsınız.
    • Diğer müşteriler, tarih saat bilgilerinin geldiği yerin yerel saatini bilmiyor
    • Diğer müşteriler, verilerin geldiği müşterinin yerel saatini değil, yalnızca veritabanından (UTC saatini kullanarak) yerel saatlerini hesaplayabilir.

Basit bir örnek, uçak bileti rezervasyon sistemidir ... Uçak bileti 2 kez içermelidir: - "kalkış" zamanı ("Kalkış" şehrin saat diliminde) - "iniş" zamanı ("Varış noktası" şehrin saat diliminde)


2
Bu, ne zaman uygun olacağı hakkında okuduğum en iyi açıklama ve çok okudum Bizim için bundan öyle görünmüyor. Dış verilerimiz için saati UTC olarak alırız ve gerekirse konumu başka bir kaynaktan biliyoruz (ve asla olmadı). Bunu bu kadar apaçık gösterdiğin için teşekkürler.
Andrew Backer

20
"datetimeoffset, UTC saatini ve AYRICA istemcinin yerel saatine göre ofseti depolar" dediniz, ancak datetimeoffset, YEREL zaman + Farkı veya UTC saati + sapma +0'a eşit depolar.
Serhii Kyslyi

DT üssü UTC olduğundan
DTO'yu bir DT'ye çevirebilmenize

2
Daha çok DateTmeOffset'in "UTC Saati ve UTC Farkı" değil, "Yerel Saat ve UTC Farkı" depolaması gibi görünüyor. Tarih saatine çevirirseniz veya veri bölümü işlevlerinden herhangi birini kullanırsanız, yerel tarih ve saat bileşenlerini alırsınız.
Triynko

" tüm istemciler tüm verilerin UTC saatini ve ayrıca bilginin geldiği yerdeki yerel saati bilir" Yine de tarih alanının bir parçası olarak depolamak bu durumda normalize edilmemiş gibi gelir. Kullanım durumu nedir - yani, neden UTC'yi kullanmazsınız ve ofseti InputLocationId(veya benzer normalleştirilmiş varlık) çekmezsiniz. Hesaplama söz konusu olabilir (merhaba, istisnalar ... özellikle siz, Indiana ), ancak bu yine de deterministik bir süreç - ve ardından uygulamanın tarih-saat mantığının dengesi basittir.
ruffin

23

UTC'yi tüm geçmiş zamanlar için kullanmakta kesinlikle haklısınız (yani gerçekleşen olayları kaydetme). UTC'den yerel saate gitmek her zaman mümkündür, ancak her zaman tam tersi olmayabilir.

Yerel saat ne zaman kullanılır? Bu soruyu cevaplayın:

Hükümet birdenbire gün ışığından yararlanma tasarrufunu değiştirmeye karar verirse, bu verilerin de değişmesini ister misiniz?

Yerel saati yalnızca yanıt "evet" ise kaydedin. Açıkçası, bu yalnızca gelecekteki tarihler için ve genellikle yalnızca insanları bir şekilde etkileyen tarihler için olacaktır.

Neden bir saat dilimi / fark saklanmalı?

İlk olarak, eylemi gerçekleştiren kullanıcı için ofsetin ne olduğunu kaydetmek istiyorsanız, muhtemelen en iyisi bunu yapmaktır, yani oturum açarken o kullanıcının yerini ve saat dilimini kaydedin.

İkincisi, görüntüleme için dönüştürmek istiyorsanız, o zaman dilimi için tüm yerel saat farkı geçişlerinin bir tablosuna sahip olmanız gerekir, sadece mevcut farkın yeterli olmadığını bilmeniz yeterli, çünkü altı ay öncesine ait bir tarih / saat gösteriyorsanız, fark farklı ol.


4
Windows UTC'den yerel saate dönüştürme, geçmiş tarihler için gün ışığından yararlanma saati değiştiğinde hesaba katılır. Bu durumda neden yerel saati kaydetmek isteyeceğinizi anlamıyorum.
jamiegs

1
@Jamiegs Windows yalnızca "son tarihsel bilgileri" (.NET DateTime belgelerinde belirtildiği / belirtildiği gibi) tarihsel olarak bilir. Kapsamlı değil.

2
tabii ki, olayın yerini de kaydetmelisiniz, aksi takdirde olayın "yerel saatte" ne olduğunu söyleyemezsiniz.
keuleJ

20

DATETIMEOFFSET, yerel saati ve UTC saatini tek bir alanda saklama yeteneği sağlar.

Bu, verileri herhangi bir şekilde görüntülemek için işlemeye gerek kalmadan yerel veya UTC saatinde çok basit ve verimli raporlama sağlar.

Bunlar en yaygın iki gereksinimdir - yerel raporlar için yerel saat ve grup raporları için UTC saati.

Yerel saat, DATETIMEOFFSET'in DATETIME bölümünde saklanır ve UTC'den OFFSET, OFFSET bölümünde saklanır, bu nedenle dönüştürme basittir ve verilerin geldiği saat dilimi hakkında bilgi gerektirmediğinden, tümü veritabanı düzeyinde yapılabilir. .

Milisaniyeye kadar olan sürelere ihtiyaç duymuyorsanız, örneğin sadece dakikalara veya saniyelere, DATETIMEOFFSET (0) kullanabilirsiniz. DATETIMEOFFSET alanı bu durumda yalnızca 8 bayt depolama gerektirir - DATETIME ile aynıdır.

Bu nedenle, UTC DATETIME yerine DATETIMEOFFSET kullanmak, raporlama için daha fazla esneklik, verimlilik ve basitlik sağlar.


Çok kötü varlık çerçevesinin, bir datetimeoffset alanının yerel tarih saatine erişme yolu yoktur, bu da belirli bir yerel tarih için sorgulamayı imkansız hale getirir.
Triynko

@Triynko ne demek istediğini açıklayabilir misin? Misal?
reidLinden
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.