DateTime'dan saat dilimini alın


103

.Net DateTime, oluşturulduğu saat dilimi hakkında bilgi içeriyor mu?

Sonunda "+ zz" olan bir formattan DateTime ayrıştıran bir kitaplığım var ve doğru bir şekilde ayrıştırıp yerel saati ayarlarken, DateTime nesnesinden belirli saat diliminin ne olduğunu almam gerekiyor.

Bu hiç mümkün mü? Tek görebildiğim DateTime.Kind, saatin yerel mi yoksa UTC mi olduğunu belirtir.


Saat dilimlerinin ve DateTimeStyles'ın işlenmesi için DateTime.Parse belgelerindeki notlara bakın . Ama hayır, istediğin gerçekten mümkün değil.
yoyo

Yanıtlar:


137

DateTime'ın kendisi gerçek saat dilimi bilgisi içermez. Bu olabilir o UTC ya da yerel olmadığını bilmek, ama ne yerel gerçekten anlamına gelir.

DateTimeOffset biraz daha iyidir - bu temelde bir UTC saati ve bir farktır. Ancak bu, saat dilimini belirlemek için hala yeterli değildir, çünkü birçok farklı saat dilimi, zamanın herhangi bir noktasında aynı sapmaya sahip olabilir. Tarih / saati ayrıştırırken üzerinde çalışmanız gereken tek şey ofset olduğu için, bu sizin için yeterince iyi gibi görünüyor.

NET 3.5'ten itibaren saat dilimleri için destek, olduğundan çok daha iyi, ancak gerçekten standart bir "BölgeselTarihSaati" veya bunun gibi bir şey görmek istiyorum - bir UTC saati ve gerçek bir saat dilimi. Kendinizinkini oluşturmak kolaydır, ancak bunu standart kütüphanelerde görmek güzel olurdu.

DÜZENLEME: Yaklaşık dört yıl sonra, şimdi daha zengin bir tarih / saat türü kümesine sahip olan Noda Time'ı kullanmanızı öneririm . Yine de Noda Time'ın ana yazarı olarak önyargılıyım :)


2
CodePlex'teki PublicDomain projhect bunu sizin için yapar.
Cheeso

BCL'deki bir Zaman Dilimi sıralaması, dünya saat dilimleri durağansa ve değişmiyorsa iyi olur.
Jeff LaFay

1
@jlafay: Ancak, değişiyorlar - örneğin geçen yıl Windows'a daha fazla saat dilimi eklendi.
Jon Skeet

Bu proje artık yazar tarafından sürdürülmemektedir; publicdomain.codeplex.com Görünüşe göre bu, kullanıma bağlı olarak, kullanmadan önce ayarlamanız yardımcı olabilir; timezone.codeplex.com
AnneTheAgile

3
@AnneTheAgile: Şahsen kendi Noda Time kitaplığımı kullanmanızı tavsiye ederim elbette :)
Jon Skeet

36

Hayır.

Bir geliştirici, bazı harici mekanizmalar aracılığıyla bir DateTime değeriyle ilişkili saat dilimi bilgilerini takip etmekten sorumludur.

Burada mükemmel bir makaleden bir alıntı . Her .Net geliştiricisi için mutlaka okunması gerekir.

Bu yüzden tavsiyem, ihtiyaçlarınıza uygun küçük bir paketleyici sınıfı yazmanız.



2

TimeZoneInfo sınıfını kullanabilirsiniz

TimeZone sınıfı yerel saat dilimini tanır ve zamanları Eşgüdümlü Evrensel Saat (UTC) ile yerel saat arasında dönüştürebilir. Bir TimeZoneInfo nesnesi, herhangi bir saat dilimini temsil edebilir ve TimeZoneInfo sınıfının yöntemleri, bir saat dilimindeki saati başka bir saat dilimindeki karşılık gelen saate dönüştürmek için kullanılabilir. TimeZoneInfo sınıfının üyeleri aşağıdaki işlemleri destekler:

  1. İşletim sistemi tarafından önceden tanımlanmış bir saat dilimini alma.

  2. Bir sistemde bulunan saat dilimlerini numaralandırma.

  3. Zamanları farklı zaman dilimleri arasında dönüştürme.

  4. İşletim sistemi tarafından henüz tanımlanmamış yeni bir saat dilimi oluşturmak.

    Daha sonra erişim için bir saat dilimini seri hale getirme.


1
... ancak bir DateTime verildiğinde, bildiğim kadarıyla DateTime'ın TimeZone'unu belirlemek için TimeZoneInfo'yu kullanmanın bir yolu yoktur.
Remi Despres-Smyth

@ RemiDespres-Smyth TimeZoneInfo'yu DateTime ile birlikte 1 sınıfta saklıyorum.
Konrad


0

Genel olarak uygulama, verileri UTC'nin "saat dilimi" ile bir DateTime olarak geçirmek ve ardından bir TimeZoneInfo nesnesini geçmek olacaktır ve verileri görüntülemeye hazır olduğunuzda, UTC DateTime'ı dönüştürmek için TimeZoneInfo nesnesini kullanırsınız.

Diğer seçenek, DateTime'ı geçerli saat dilimiyle ayarlamak ve daha sonra DateTime nesnesi için "saat diliminin" bilinmediğinden emin olmak, ardından DateTime'ın geçtiği Tarih Saatinin Saat Dilimini gösteren bir TimeZoneInfo ile tekrar geçtiğinden emin olmaktır.

Diğerlerinin de burada belirttiği gibi, Microsoft bunun üstüne çıkıp hepsini yapmak için güzel bir nesne oluştursa iyi olur, ancak şimdilik iki nesne ile uğraşmak zorundasınız.


0

DateTime, saat dilimi farkını bilmiyor. Farkı veya saat dilimi adını döndürmek için yerleşik bir yöntem yoktur (örn. EAT, CEST, EST vb.).

Başkalarının önerdiği gibi, tarihinizi UTC'ye dönüştürebilirsiniz:

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

ve sonra yalnızca farkı hesaplayın:

TimeSpan difference = localtime - utctime;

Ayrıca DateTimeOffset'i kullanarak bir zamanı diğerine dönüştürebilirsiniz:

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

Ancak bu, kayıplı bir sıkıştırma türüdür - iki farklı ülke farklı zaman dilimlerinde olabileceğinden ve yalnızca yılın bir bölümünde (örneğin Güney Afrika ve Avrupa) aynı saate sahip olabileceğinden, tek başına dengeleme size hangi saat diliminde olduğunu söyleyemez. Ayrıca, yaz gün ışığından yararlanma saatinin farklı tarihlerde uygulanabileceğini unutmayın (EST - CET - 3 haftalık fark).

TimeZoneInfo sınıfını kullanarak yerel sistem saat diliminizin adını alabilirsiniz:

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

Gerrie Schenck'e katılıyorum, lütfen önerdiği makaleyi okuyun.

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.