DateTime “null” değeri


273

Çok araştırıyorum ama bir çözüm bulamadım. Başlatılmamış bir değer (null değerine eşdeğer) içermesi gereken bir DateTime ile nasıl başa çıkıyorsunuz? Bir DateTime özellik değeri ayarlanmış olabilir ya da olmayabilir bir sınıf var. Ben daha sonra kolayca kontrol edilebilir DateTime.MinValue, özellik sahibi başlatmayı düşünüyordum. Sanırım bu oldukça yaygın bir soru, bunu nasıl yapıyorsunuz?

Yanıtlar:


420

Normal DateTimes için, onları hiç başlatmazsanız eşleşirler DateTime.MinValue, çünkü bu bir referans türü yerine bir değer türüdür.

Aynı şekilde bir nulllable DateTime da kullanabilirsiniz:

DateTime? MyNullableDate;

Veya daha uzun form:

Nullable<DateTime> MyNullableDate;

Ve son olarak, herhangi bir türün varsayılanını referans almak için yerleşik bir yol var. Bu null, başvuru türleri için döner , ancak DateTime örneğimiz için şu ile aynı döndürülür DateTime.MinValue:

default(DateTime)

veya C # 'ın daha yeni sürümlerinde,

default

8
Nasıl kullanılacağına dair bir örnek verirseniz çok yardımcı olacaktır. DBNull olabilen veritabanındaki DateTime'ı nullable DateTime'a nasıl atarsınız?
kirk.burleson

9
Bunları ve Boş ile başlatmak DO, onlar atanmış olduğunu ayrıca not iyidir DateTime.MinValuesıra
Jeff LAFAY

2
@ kirk.burleson ayrı bir soruya benziyor.
CompuChip

Eğer gerekir MyNullableDate=date; , bunu ayarlamak için MyDate = MyNullableDate.Value;ondan okumak için ve if(MyNullableDate.HasValue)o boş olup olmadığını kontrol etmek
satibel

Yanıtlayıcının "son olarak" biraz açıklığa kavuşturulması için - Nullable <TateTime> (DateTime?) Varsayılan değeri null, çünkü Nullable <T> bir başvuru türü oluşturur.
ryanwebjackson

88

.NET 2.0 (veya üstü) kullanıyorsanız, null olabilecek türü kullanabilirsiniz:

DateTime? dt = null;

veya

Nullable<DateTime> dt = null;

daha sonra:

dt = new DateTime();

Ve değeri şununla kontrol edebilirsiniz:

if (dt.HasValue)
{
  // Do something with dt.Value
}

Veya şu şekilde kullanabilirsiniz:

DateTime dt2 = dt ?? DateTime.MinValue;

Daha fazla bilgiyi buradan edinebilirsiniz:
http://msdn.microsoft.com/en-us/library/b3h38hb0.aspx


1
Null olabilecek türleri .NET'in önceki sürümlerinde bile kullanabilirsiniz, 3.0'a gerek yoktur.
stephenbayer

1
.NET 2.0'da geldi değil mi? ? sözdizimi VB.NET 3.5'te eklendi, ama inanıyorum 2.0 beri C # olmuştur.
David Mohundro

1
Null olabilecek türler .Net 2.0'da mevcuttur. C # stenografi oldu? 2.0'dan notasyon. Sadece VB.Net'in kestirmesi yoktu? 2.0'da ancak Nullable (Of DateTime)
Mendelt'i kullanabilirsiniz

Son snippet için DateTime dt2 = dt ?? DateTime.MaxValue'dan;
Joel Coehoorn

Kullanırdım dt.GetValueOrDefault()- bu en verimli seçenektir.
CompuChip

37

DateTime? MyDateTime {get; set;}

MyDateTime = (dr["f1"] == DBNull.Value) ? (DateTime?)null : ((DateTime)dr["f1"]);

1
Bu, geçişin nullişe yaramadığını keşfetmeme yardımcı oldu . Olması gerekiyor (DateTime?)null.
Inphinite Phractals

33

Aşağıdaki yol da işe yarıyor

myClass.PublishDate = toPublish ? DateTime.Now : (DateTime?)null;

PublishDate özelliğinin DateTime olması gerektiğini lütfen unutmayın?



8

Bir DateTimedeğişken olamazken, nullyine de nullbir derleyici hatası olmadan karşılaştırılabileceğini belirtmek gerekir :

DateTime date;
...
if(date == null) // <-- will never be 'true'
  ...

6

Sıfırlanabilir bir sınıf kullanabilirsiniz.

DateTime? date = new DateTime?();

Muhtemelen bunun size bir null değeri olmayanı örneklemekten farklı bir davranış kazandıracağını belirtmek gerekir DateTime. Daha önce de belirtildiği gibi new DateTime(), etkin bir şekilde verirken DateTime.Minoysa new DateTime?()null ile sonuçlanır.
Vitoc

6

Bunun için boş bir DateTime kullanabilirsiniz.

Nullable<DateTime> myDateTime;

veya şu şekilde yazılmış aynı şey:

DateTime? myDateTime;

6

DateTime'ı Nullable olarak ayarlayabilirsiniz. Varsayılan olarak DateTime geçersizdir. Birkaç şekilde null edilebilir yapabilirsiniz. DateTime yazdıktan sonra soru işareti mi kullanıyorsunuz? myTime veya Nullable genel stilini kullanarak.

DateTime? nullDate = null;

veya

DateTime? nullDate;

5

Her zaman zamanı ayarladım DateTime.MinValue. Bu şekilde herhangi bir NullErrorException almazsınız ve ben bilmediğim bir tarihle karşılaştırabilirsiniz.


8
Bu, "Gerçekten bir DateTime'a ihtiyacım var" ve "İsteğe bağlı" arasındaki farkı söyleyemeyeceğiniz anlamına gelir - Nullable <DateTime> çok daha iyi bir çözümdür, IMO.
Jon Skeet

? Yorumunu gerçekten alamadım. Evet biliyorum DateTime şimdiye kadar gerçeğin çok uzak olduğu gibi eğer boş ...
Patrick Desjardins

2
Bu uygun, ancak DateTime.MinValue değer olarak, özel bir durum koşulu olarak görüntülüyorum. Sadece çizgide sorunlara yol açabilir. Nullable <TateTime> ile giderdim.
spoulson

3
Sanırım cevabım hakkında bir şey özledin, Spoulson bir şeyler yazdı ve ben de cevap veriyordum. Kamu üyeleri hakkında, aynı değil ve bunu biliyorsunuz. Dize gibi. Boş veya boş. Her ikisi de yapabilirsiniz, çünkü String.Empty null yanlış olduğundan daha iyidir. Her neyse.
Patrick Desjardins

1
Bu konuda Daok ile birlikteyim. "Kitap tarafından" yaklaşım olmayabilir ama NullReferenceException almak veya hantal Nullable türü ile uğraşmak daha iyidir. Ayrıca, aslında 1 Ocak 1 AD tarihini referans alması gereken kaç başvuru var?
Jacobs Data Solutions

4

Sadece uyarılırsınız - Bir Nullable kullanırken artık 'saf' bir datetime nesnesi olmadığı için DateTime üyelerine doğrudan erişemezsiniz. Açıklamaya çalışacağım.

Nullable <> kullanarak, DateTime'ı temel olarak null olabilecek bir kapta (teşekkür jenerikleri) sarıyorsunuz - açıkça amacı. Bu kapsayıcı, yukarıda belirtilen DateTime nesnesine erişim sağlayacak çağırabileceğiniz kendi özelliklerine sahiptir; doğru özelliği kullandıktan sonra - bu durumda Nullable.Value - standart DateTime üyelerine, özelliklerine vb. erişebilirsiniz.

Şimdi - DateTime nesnesine erişmenin en iyi yolu konusunda sorun akla geliyor. Birkaç yolu vardır, 1 numara FAR tarafından en iyisi ve 2 "ahbap neden" dir.

  1. Nullable.Value özelliğini kullanarak,

    DateTime date = myNullableObject.Value.ToUniversalTime(); //Works

    DateTime date = myNullableObject.ToUniversalTime(); //Not a datetime object, fails

  2. Convert.ToDateTime () kullanarak nullable nesnesini datetime değerine dönüştürme,

    DateTime date = Convert.ToDateTime(myNullableObject).ToUniversalTime(); //works but why...

Bu noktada cevap iyi belgelenmiş olmasına rağmen, Nullable kullanımının muhtemelen yayınlanmaya değer olduğuna inanıyorum. Kabul etmiyorsanız üzgünüm.

edit: Biraz fazla belirgin ve büyük / küçük harf bağımlı olduğu için üçüncü bir seçenek kaldırıldı.


2

Herkes size zaten cevap vermiş olsa da, bir tarih saatini bir işleve geçirmeyi kolaylaştıran bir yoldan bahsedeceğim

[HATA: system.datetime dönüştürülemiyor mu? to system.datetime]

DateTime? dt = null;
DateTime dte = Convert.ToDateTime(dt);

Artık herhangi bir sorun olmadan fonksiyonun içinde dte iletebilirsiniz.


1

Eğer bazen null bekliyoruz, böyle bir şey kullanabilirsiniz:

var orderResults = Repository.GetOrders(id, (DateTime?)model.DateFrom, (DateTime?)model.DateTo)

Deponuzda null kullanabilen tarih kullanın.

public Orders[] GetOrders(string id, DateTime? dateFrom, DateTime? dateTo){...}

1

Throws ArgumentNullException için Unit testi yaparken DateTime için bir parametre olarak Null vermek zorunda aynı sorun vardı.Aşağıdaki seçeneği kullanarak benim durumumda çalıştı:

Assert.Throws<ArgumentNullException>(()=>sut.StartingDate = DateTime.Parse(null));

0

Tarih / saat veri türünün doğası göz önüne alındığında, bir nulldeğer içeremez , yani bir değer içermesi gerekir, boş olamaz veya hiçbir şey içeremez. Bir tarih / saat değişkenini nullableyalnızca olarak işaretlerseniz, bu değişkene yalnızca bir boş değer atayabilirsiniz. Yapmak istediğiniz iki şeyden biri (daha fazlası olabilir ama sadece iki tane düşünebilirim):

  • Değişkeniniz için bir değeriniz yoksa, değişkeninize minimum bir tarih / saat değeri atayın. Hangi tarihte olursa olsun, maksimum tarih / saat değeri de atayabilirsiniz. Tarih / saat değerlerinizi kontrol ederken site genelinde tutarlı olduğunuzdan emin olmanız yeterlidir. minVeya kullanmaya karar verin maxve buna bağlı kalın.

  • Tarih / saat değişkeninizi olarak işaretleyin nullable. Bu şekilde, değişkeniniz yoksa tarih / saat değişkeninizi olarak ayarlayabilirsiniz null.

İlk örneğimi bir örnek kullanarak göstereyim. DateTimeDeğişken türü ben bunu ayarlamak için gidiyorum bu durumda, bir değeri ihtiyacı null ayarlanamaz DateTimehiçbir değer yoksa 'ın minimum değer.

Benim senaryom bir BlogPostders var. Birçok farklı alan / özellik var ama ben sadece bu örnek için iki kullanmayı seçti. DatePublished, yayının web sitesinde yayınlandığı ve bir tarih / saat değeri içermesi gereken zamandır. DateModified, bir gönderinin değiştirildiği zamandır, bu nedenle bir değer içermesi gerekmez, ancak bir değer içerebilir.

public class BlogPost : Entity
{
     public DateTime DateModified { get; set; }

     public DateTime DatePublished { get; set; }
}

ADO.NETVeritabanından veri almak için kullanma (atama DateTime.MinValuedeğeri yoktur):

BlogPost blogPost = new BlogPost();
blogPost.DateModified = sqlDataReader.IsDBNull(0) ? DateTime.MinValue : sqlDataReader.GetFieldValue<DateTime>(0);
blogPost.DatePublished = sqlDataReader.GetFieldValue<DateTime>(1);

DateModifiedAlanı ikinci olarak işaretleyerek ikinci noktamı başarabilirsiniz nullable. Şimdi bunun için bir nulldeğer yoksa şu şekilde ayarlayabilirsiniz :

public DateTime? DateModified { get; set; }

ADO.NETVeritabanından veri almak için kullanıldığında , yukarıda yapıldığı yöntemden biraz farklı görünecektir ( nullyerine atama DateTime.MinValue):

BlogPost blogPost = new BlogPost();
blogPost.DateModified = sqlDataReader.IsDBNull(0) ? (DateTime?)null : sqlDataReader.GetFieldValue<DateTime>(0);
blogPost.DatePublished = sqlDataReader.GetFieldValue<DateTime>(1);

Umarım bu herhangi bir karışıklığı gidermeye yardımcı olur. Cevabım yaklaşık 8 yıl sonra göz önüne alındığında, muhtemelen şu an uzman bir C # programcısısınız :)

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.