Verifica se a una variabile DateTime è stato assegnato un valore


131

Esiste un modo semplice in C # per verificare se a un'istanza di DateTime è stato assegnato un valore o no?

Risposte:


83

L'unico modo per avere una variabile a cui non è stato assegnato un valore in C # è che sia una variabile locale - nel qual caso in fase di compilazione puoi dire che non è definitivamente assegnata cercando di leggere da essa: )

Ho il sospetto che tu voglia davvero Nullable<DateTime>(o DateTime?con lo zucchero sintattico C #) - fai in modo che nullinizi e poi assegni un DateTimevalore normale (che verrà convertito in modo appropriato). Quindi puoi solo confrontare con null(o utilizzare la HasValueproprietà) per vedere se è stato impostato un valore "reale".


che ne dite di verificare se il valore è uguale al valore datetime predefinito. C'è qualche svantaggio impercettibile in questo approccio? if (request.StartDateTime == default (DateTime) {request.StartDateTime = DateTime.Now;}
Menol

8
@Menol: Beh, questo non dice la differenza tra un campo a cui è stato deliberatamente dato un valore default(DateTime)e uno che era proprio così per cominciare. Fondamentalmente sta trattando un valore all'interno del dominio come "speciale e non disponibile per l'uso normale" che non mi piace.
Jon Skeet,

298

vuoi dire così:

DateTime datetime = new DateTime();

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

oppure potresti usare Nullable

DateTime? datetime = null;

 if (!datetime.HasValue)
 {
     //unassigned
 }

5
Solo il secondo è a prova di proiettile. Il primo presuppone qualcosa sulla rappresentazione non impostata di un DateTime che non è garantita dal framework. Personalmente penso che avrebbero dovuto aggiungere un membro statico Unset per questo scenario.
Rupert Rawnsley,

18
Per aggiungere ciò che ha detto @RupertRawnsley, dovresti effettivamente confrontare con il valore predefinito (DateTime), che è il valore di un DateTime non assegnato. Sembra che sia uguale a MinValue, ma potrebbe cambiare.
Tsahi Asher,

32

metti questo da qualche parte:

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

poi:

DateTime datetime = ...;

if (datetime.IsEmpty())
{
    //unassigned
}

Mi piace questa idea, ma nota che nell'improbabile eventualità che alla variabile DateTime sia stato assegnato un valore che risulta essere il valore predefinito, questo metodo di estensione restituirà il risultato errato. L'unico modo per evitarlo è utilizzare un DateTime nullable, che è già stato suggerito. Mi piace ancora (e ora sto usando) la tua risposta, grazie!
Klicker,

@Klicker: grazie per il tuo bel commento, ma non sono sicuro di aver capito la tua osservazione. Per quanto posso dire == in questo caso tornerà sempre vero quando datetime è equivalente a default (DateTime) qualunque sia il modo in cui datetime finisce con l'assegnazione del valore predefinito. Lasciami spiegare: in realtà il secondo frammento nella mia risposta è sbagliato, non verrà compilato, perché, se consideri che questo è il corpo di una funzione, il datetime non è assegnato e il compilatore rifiuterà di usarlo. Quindi dovrai assegnargli un valore. Può essere predefinito (DateTime) direttamente o indirettamente. Modificherò la mia risposta.
Sonatique,

e se in un altro contesto datetime è un membro di una classe e viene lasciato così com'è, il runtime gli assegnerà il default (DateTime). Il == per le strutture confronta effettivamente il contenuto della struttura, qualunque sia il modo in cui la struttura finisce per riempire con questo contenuto.
Sonatique,

Il mio punto riguarda solo i membri della classe, e ciò che intendo è; se si dispone di un campo datetime livello di classe o di proprietà che è stato assegnato al MinValue, il vostro IsEmptymetodo restituirà vero, che probabilmente non è quello che si vuole (perché è non è vuoto - è stato assegnato il valore di default). Immagino che il nome del tuo metodo sarebbe più adatto come IsDefaultValue. Dal momento che non puoi davvero avere un DateTime non annullabile quello IsEmpty.
Klicker,

@Klicker: ah sì, ok, capito. Hai ragione: il nome che ho scelto è fuorviante. IsDefaultValuesarebbe stato meglio
Sonatique,

5

DateTime è un tipo di valore, quindi non può mai essere nullo. Se pensi che DateTime? (Nullable) è possibile utilizzare:

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

5

Ho appena scoperto che GetHashCode () per un datetime non assegnato è sempre zero. Non sono sicuro se questo è un buon modo per verificare la presenza di un datetime nullo, perché non riesco a trovare alcuna documentazione sul motivo per cui questo comportamento viene visualizzato.

if(dt.GetHashCode()==0)
{
    Console.WriteLine("DateTime is unassigned"); 
} 

1
GetHashCoderestituisce 0 perché di zecche (rappresentazione interna di DateTime) sono uguali a 0. codice hash calcolato con la seguente modo: unchecked((int)ticks) ^ (int)(ticks >> 32);. Vedi anche qui: riferimentiource.microsoft.com/#mscorlib/system/datetime.cs.836
Ivan Kochurkin,

Grazie mille. Sto cercando di serializzare un file XML da una classe C # ed escludere gli attributi null. Questo ha aiutato.
Jim Neff,


3

Direi che il valore predefinito è sempre new DateTime(). Quindi possiamo scrivere

DateTime datetime;

if (datetime == new DateTime())
{
    //unassigned
}

2
Questa soluzione è già stata fornita da + Hath nel 2008 e, come ha aggiunto + Rupert Rawnsley come commento, non è a prova di proiettile ...
Roland Bär,

0

In genere preferisco, ove possibile, utilizzare il valore predefinito dei tipi di valore per determinare se sono stati impostati. Questo ovviamente non è sempre possibile, specialmente con ints - ma per DateTimes, penso che riservare MinValue per indicare che non è stato modificato sia abbastanza giusto. Il vantaggio di questo su nullable è che c'è un posto in meno in cui otterrai un'eccezione di riferimento null (e probabilmente molti posti in cui non è necessario verificare la presenza di null prima di accedervi!)


0

Se non vuoi preoccuparti di problemi di valore Null come il controllo di null ogni volta che lo usi o lo avvolgi in una logica, e non devi preoccuparti di problemi di tempo di offset, allora questo è come ho risolto il problema:

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

Controllo solo che il valore predefinito sia inferiore a un giorno dopo l'inizio del tempo. Funziona come un fascino.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.