Überprüfen Sie, ob einer DateTime-Variablen ein Wert zugewiesen wurde

131

Gibt es eine einfache Möglichkeit in C # zu überprüfen, ob einer DateTime-Instanz ein Wert zugewiesen wurde oder nicht?

Muhen
quelle

Antworten:

82

Die einzige Möglichkeit, einer Variablen, der in C # kein Wert zugewiesen wurde, eine lokale Variable zuzuweisen, besteht darin, dass Sie beim Kompilieren feststellen können, dass sie nicht definitiv zugewiesen ist, indem Sie versuchen, daraus zu lesen: )

Ich vermute, Sie möchten wirklich Nullable<DateTime>(oder DateTime?mit dem syntaktischen C # -Zucker) - machen Sie es nullzunächst und weisen Sie dann einen normalen DateTimeWert zu (der entsprechend konvertiert wird). Dann können Sie einfach mit vergleichen null(oder die HasValueEigenschaft verwenden), um festzustellen, ob ein "realer" Wert festgelegt wurde.

Jon Skeet
quelle
Wie wäre es zu überprüfen, ob der Wert dem Standardwert für Datum und Uhrzeit entspricht? Gibt es einen nicht wahrnehmbaren Nachteil dieses Ansatzes? if (request.StartDateTime == default (DateTime) {request.StartDateTime = DateTime.Now;}
Menol
8
@Menol: Nun, das macht keinen Unterschied zwischen einem Feld, dem absichtlich der Wert gegeben wurde, default(DateTime)und einem Feld, das genau so war. Grundsätzlich wird ein Wert innerhalb der Domain als "speziell und für den normalen Gebrauch nicht verfügbar" behandelt, was mir nicht gefällt.
Jon Skeet
298

meinst du so:

DateTime datetime = new DateTime();

if (datetime == DateTime.MinValue)
{
    //unassigned
}

oder Sie könnten Nullable verwenden

DateTime? datetime = null;

 if (!datetime.HasValue)
 {
     //unassigned
 }
Hath
quelle
5
Nur die zweite davon ist kugelsicher. Die erste setzt etwas über die nicht festgelegte Darstellung einer DateTime voraus, das vom Framework nicht garantiert wird. Persönlich denke ich, dass sie für dieses Szenario ein nicht gesetztes statisches Mitglied hinzugefügt haben sollten.
Rupert Rawnsley
18
Um das hinzuzufügen, was @RupertRawnsley gesagt hat, sollten Sie tatsächlich mit dem Standardwert (DateTime) vergleichen, der der Wert einer nicht zugewiesenen DateTime ist. Es ist zufällig gleich MinValue, aber es könnte sich ändern.
Tsahi Asher
32

lege das irgendwo hin:

public static class DateTimeUtil //or whatever name
{
    public static bool IsEmpty(this DateTime dateTime)
    {
        return dateTime == default(DateTime);
    }
}

dann:

DateTime datetime = ...;

if (datetime.IsEmpty())
{
    //unassigned
}
Sonatique
quelle
Ich mag diese Idee, aber beachte, dass in dem etwas unwahrscheinlichen Fall, dass der DateTime-Variablen ein Wert zugewiesen wurde, der zufällig der Standardwert ist, diese Erweiterungsmethode das falsche Ergebnis zurückgibt. Die einzige Möglichkeit, dies zu vermeiden, besteht darin, eine nullbare DateTime zu verwenden, die bereits vorgeschlagen wurde. Ich mag Ihre Antwort immer noch sehr (und benutze sie jetzt), danke!
Klicker
@Klicker: Danke für deinen netten Kommentar, aber ich bin mir nicht sicher, ob ich deine Bemerkung verstehe. Soweit ich das beurteilen kann, wird == in diesem Fall immer true zurückgeben, wenn datetime dem Standardwert (DateTime) entspricht, unabhängig davon, wie datetime end-up der Standardwert zugewiesen wird. Lassen Sie mich erklären: Tatsächlich ist das zweite Snippet in meiner Antwort falsch, es wird nicht kompiliert, denn wenn Sie bedenken, dass dies der Hauptteil einer Funktion ist, ist datetime nicht zugewiesen und der Compiler wird die Verwendung ablehnen. Sie müssen ihm also einen Wert zuweisen. Es kann direkt oder indirekt die Standardeinstellung (DateTime) sein. Ich werde meine Antwort ändern.
Sonatique
und wenn in einem anderen Kontext datetime ein Mitglied einer Klasse ist und diese unverändert bleibt, weist die Laufzeit ihr die Standardeinstellung (DateTime) zu. Das == für Strukturen vergleicht tatsächlich den Inhalt der Struktur, unabhängig davon, wie die Struktur mit diesem Inhalt gefüllt ist.
Sonatique
Mein Punkt bezieht sich wirklich nur auf Klassenmitglieder, und was ich meine, ist; Wenn Sie ein DateTime-Feld oder eine DateTime-Eigenschaft auf Klassenebene haben, der Sie MinValue zugewiesen haben, gibt Ihre IsEmptyMethode true zurück, was wahrscheinlich nicht das ist, was Sie möchten (da es nicht leer ist - ihm wurde der Standardwert zugewiesen). Ich denke, der Name Ihrer Methode wäre besser geeignet als IsDefaultValue. Da kann man eigentlich keine nicht nullbare DateTime haben IsEmpty.
Klicker
@Klicker: ah ja, OK, verstanden. Sie haben Recht: Der Name, den ich gewählt habe, ist irreführend. IsDefaultValuewäre besser gewesen
Sonatique
5

DateTime ist ein Werttyp, daher kann er niemals null sein. Wenn Sie DateTime denken? (Nullable) können Sie verwenden:

DateTime? something = GetDateTime();
bool isNull = (something == null);
bool isNull2 = !something.HasValue;
TcKs
quelle
5

Ich habe gerade herausgefunden, dass GetHashCode () für eine nicht zugewiesene Datumszeit immer Null ist. Ich bin nicht sicher, ob dies eine gute Möglichkeit ist, nach null datetime zu suchen, da ich keine Dokumentation dazu finden kann, warum dieses Verhalten angezeigt wird.

if(dt.GetHashCode()==0)
{
    Console.WriteLine("DateTime is unassigned"); 
} 
Arcturus
quelle
1
GetHashCodeGibt 0 zurück, da Ticks (interne Darstellung von DateTime) ebenfalls gleich 0 sind. Hash-Code wird folgendermaßen berechnet : unchecked((int)ticks) ^ (int)(ticks >> 32);. Siehe auch hier: referencesource.microsoft.com/#mscorlib/system/datetime.cs,836
Ivan Kochurkin
Vielen Dank. Ich versuche, eine XML-Datei aus einer C # -Klasse zu serialisieren und die Nullattribute auszuschließen. Das hat geholfen.
Jim Neff
5

Verwenden Sie, Nullable<DateTime>wenn möglich.

Baretta
quelle
3

Ich würde sagen, der Standardwert ist immer new DateTime(). Also können wir schreiben

DateTime datetime;

if (datetime == new DateTime())
{
    //unassigned
}
Sabine
quelle
2
Diese Lösung wurde bereits 2008 von + Hath gegeben und ist, wie + Rupert Rawnsley als Kommentar hinzufügte, nicht kugelsicher ...
Roland Bär
0

Im Allgemeinen bevorzuge ich es, wenn möglich, den Standardwert von Werttypen zu verwenden, um festzustellen, ob sie festgelegt wurden. Dies ist natürlich nicht immer möglich, insbesondere bei Ints - aber für DateTimes halte ich es für fair genug, den MinValue zu reservieren, um anzuzeigen, dass er nicht geändert wurde. Dies hat gegenüber nullables den Vorteil, dass es eine Stelle weniger gibt, an der Sie eine Nullreferenzausnahme erhalten (und wahrscheinlich viele Stellen, an denen Sie vor dem Zugriff nicht auf null prüfen müssen!).

Steve Dunn
quelle
0

Wenn Sie sich nicht um Nullwertprobleme kümmern müssen, z. B. jedes Mal, wenn Sie es verwenden, nach Null suchen oder es in eine Logik einwickeln möchten, und Sie sich auch nicht um Probleme mit der Versatzzeit kümmern müssen, dann ist dies der Fall wie ich das Problem gelöst habe:

startDate = startDate < DateTime.MinValue.AddDays(1) ? keepIt : resetIt

Ich überprüfe nur, ob der Standardwert weniger als einen Tag nach Beginn der Zeit liegt. Klappt wunderbar.

Urasquirrel
quelle