Come convalidare un DateTime in C #?


118

Dubito di essere l'unico che ha trovato questa soluzione, ma se ne hai una migliore, per favore pubblicala qui. Voglio semplicemente lasciare questa domanda qui in modo che io e altri possiamo cercarla in un secondo momento.

Avevo bisogno di dire se una data valida era stata inserita in una casella di testo e questo è il codice che mi è venuto in mente. Lo sparo quando lo stato attivo lascia la casella di testo.

try
{
    DateTime.Parse(startDateTextBox.Text);
}
catch
{
    startDateTextBox.Text = DateTime.Today.ToShortDateString();
}

1
<sarcasm> a giudicare dalle risposte, penso che dovrei usare TryParse </sarcasm> Grazie per le ottime risposte ragazzi. Non avevo nemmeno pensato a TryParse
Matt

2
Un esempio di una domanda facile da google che se qualcuno chiedesse oggi sarebbe ingiustamente chiusa per "non abbastanza ricerca".
live-love

1
qui è un modo semplice per fare questo senza l'uso di funzioni speciali: < stackoverflow.com/questions/14917203/... >
Zameer


2
Lavorare con DateTimes è sempre una seccatura. Grazie
Gonzo345

Risposte:


269
DateTime.TryParse

Questo credo sia più veloce e significa che non devi usare brutti tentativi / catture :)

per esempio

DateTime temp;
if(DateTime.TryParse(startDateTextBox.Text, out temp))
{
  // Yay :)
}
else
{
  // Aww.. :(
}

2
Correggimi se sbaglio, ma in C # (al contrario, diciamo, JavaScript) un ramo if / else non richiede parentesi graffe? Non fraintendermi, non sto cercando di esaminare attentamente, è una risposta fantastica e sto facendo +1 perché mi ha aiutato, ma ho solo pensato, dato che non sai mai come sono i nuovi utenti futuri quando visualizzi le risposte già pubblicate, questo potrebbe confonderli. Ovviamente, se hai problemi con le parentesi graffe in C #, questa domanda sarebbe l'ultima delle tue preoccupazioni ...
VoidKing

2
@VoidKing Hai ragione riguardo alle parentesi graffe, ma se hai solo 1 istruzione in quel blocco non devi usarle. Questo vale anche in altre lingue, ma posso vedere come questo possa essere fuorviante per i programmatori più recenti.
D.Galvez

2
@ D.Galvez Scusa il mio ritardo alla festa, ma è una buona pratica includere le parentesi anche se c'è solo 1 affermazione? Questa potrebbe essere solo una situazione in cui le preferenze personali sono più importanti - e in tal caso trovo che includerle sia abbastanza piacevole semplicemente per leggibilità e coerenza.
Nick

2
Non sapevo 6 anni fa che si sarebbe verificato un simile dibattito sulle parentesi.
qui il

È possibile accorciare l'inizializzazione della variabile con if(DateTime.TryParse(startDateTextBox.Text, out var temp)):)
Alexandre Daubricourt

61

Non utilizzare eccezioni per il controllo del flusso. Usa DateTime.TryParse e DateTime.TryParseExact . Personalmente preferisco TryParseExact con un formato specifico, ma immagino che ci siano momenti in cui TryParse è migliore. Esempio di utilizzo basato sul codice originale:

DateTime value;
if (!DateTime.TryParse(startDateTextBox.Text, out value))
{
    startDateTextox.Text = DateTime.Today.ToShortDateString();
}

Motivi per preferire questo approccio:

  • Codice più chiaro (dice cosa vuole fare)
  • Prestazioni migliori rispetto alla cattura e alla deglutizione delle eccezioni
  • Questo non rileva eccezioni in modo inappropriato, ad esempio OutOfMemoryException, ThreadInterructedException. (Il codice corrente potrebbe essere corretto per evitarlo semplicemente rilevando l'eccezione pertinente, ma sarebbe comunque meglio usare TryParse.)

24

Ecco un'altra variante della soluzione che restituisce true se la stringa può essere convertita in un DateTimetipo e false in caso contrario.

public static bool IsDateTime(string txtDate)
{
    DateTime tempDate;
    return DateTime.TryParse(txtDate, out tempDate);
}

3
Benvenuto in StackOverflow! Si prega di guardare le risposte che sono già state fornite, soprattutto quando si risponde a una domanda che ha più di tre anni ed è stata risolta con successo. La tua risposta è già stata coperta da precedenti intervistati.
Bob Kaufman



3

Un problema con l'utilizzo DateTime.TryParseè che non supporta il caso d'uso di immissione dati molto comune di date immesse senza separatori, ad es 011508.

Ecco un esempio di come supportarlo. (Questo proviene da un framework che sto costruendo, quindi la sua firma è un po 'strana, ma la logica di base dovrebbe essere utilizzabile):

    private static readonly Regex ShortDate = new Regex(@"^\d{6}$");
    private static readonly Regex LongDate = new Regex(@"^\d{8}$");

    public object Parse(object value, out string message)
    {
        msg = null;
        string s = value.ToString().Trim();
        if (s.Trim() == "")
        {
            return null;
        }
        else
        {
            if (ShortDate.Match(s).Success)
            {
                s = s.Substring(0, 2) + "/" + s.Substring(2, 2) + "/" + s.Substring(4, 2);
            }
            if (LongDate.Match(s).Success)
            {
                s = s.Substring(0, 2) + "/" + s.Substring(2, 2) + "/" + s.Substring(4, 4);
            }
            DateTime d = DateTime.MinValue;
            if (DateTime.TryParse(s, out d))
            {
                return d;
            }
            else
            {
                message = String.Format("\"{0}\" is not a valid date.", s);
                return null;
            }
        }

    }

Non sono preoccupato per i seporatori nel mio caso perché sto usando una casella di testo mascherata, ma posso vedere come sarebbe utile in altre situazioni che potrei incontrare con questa app.
Matt

Qual è il motivo per utilizzare la stringa DateTime senza separatori?
Sergei Kovalenko

1
    protected bool ValidateBirthday(String date)
    {
        DateTime Temp;

        if (DateTime.TryParse(date, out Temp) == true &&
      Temp.Hour == 0 &&
      Temp.Minute == 0 &&
      Temp.Second == 0 &&
      Temp.Millisecond == 0 &&
      Temp > DateTime.MinValue)
            return true;
        else
            return false;
    }

// supponiamo che la stringa di input sia un formato di data breve.
ad esempio "2013/7/5" restituisce true o
"2013/2/31" restituisce false.
http://forums.asp.net/t/1250332.aspx/1
// bool booleanValue = ValidateBirthday ("12:55"); restituisce false


1
private void btnEnter_Click(object sender, EventArgs e)
{
    maskedTextBox1.Mask = "00/00/0000";
    maskedTextBox1.ValidatingType = typeof(System.DateTime);
    //if (!IsValidDOB(maskedTextBox1.Text)) 
    if (!ValidateBirthday(maskedTextBox1.Text))
        MessageBox.Show(" Not Valid");
    else
        MessageBox.Show("Valid");
}
// check date format dd/mm/yyyy. but not if year < 1 or > 2013.
public static bool IsValidDOB(string dob)
{ 
    DateTime temp;
    if (DateTime.TryParse(dob, out temp))
        return (true);
    else 
        return (false);
}
// checks date format dd/mm/yyyy and year > 1900!.
protected bool ValidateBirthday(String date)
{
    DateTime Temp;
    if (DateTime.TryParse(date, out Temp) == true &&
        Temp.Year > 1900 &&
       // Temp.Hour == 0 && Temp.Minute == 0 &&
        //Temp.Second == 0 && Temp.Millisecond == 0 &&
        Temp > DateTime.MinValue)
        return (true);
    else
        return (false);
}

1

Tutte le risposte sono ottime, ma se vuoi usare una singola funzione, potrebbe funzionare.

private bool validateTime(string dateInString)
{
    DateTime temp;
    if (DateTime.TryParse(dateInString, out temp))
    {
       return true;
    }
    return false;
}

1
Che ne dici di restituire il risultato di DateTime.TryParse () invece del blocco "if"? Inoltre, il tuo IDE si lamenterebbe del temp mai usato, che potresti dichiarare all'interno della chiamata di funzione direttamente come "out DateTime temp".
Sergei Kovalenko

0

Puoi anche definire il DateTimeformato per uno specificoCultureInfo

public static bool IsDateTime(string tempDate)
{
    DateTime fromDateValue;
    var formats = new[] { "MM/dd/yyyy", "dd/MM/yyyy h:mm:ss", "MM/dd/yyyy hh:mm tt", "yyyy'-'MM'-'dd'T'HH':'mm':'ss" };
    return DateTime.TryParseExact(tempDate, formats, System.Globalization.CultureInfo.InvariantCulture, System.Globalization.DateTimeStyles.None, out fromDateValue);
}

-1
protected static bool CheckDate(DateTime date)
{
    if(new DateTime() == date)      
        return false;       
    else        
        return true;        
} 

2
Sebbene questo codice possa risolvere la domanda, inclusa una spiegazione di come e perché questo risolve il problema aiuterebbe davvero a migliorare la qualità del tuo post e probabilmente si tradurrebbe in più voti positivi. Ricorda che stai rispondendo alla domanda per i lettori in futuro, non solo alla persona che chiede ora. Si prega di modificare la risposta per aggiungere spiegazioni e dare un'indicazione di ciò si applicano le limitazioni e le assunzioni.
Brian

La domanda è chiedere come convalidare un valore stringche potrebbe o non potrebbe contenere un DateTImevalore. Stai verificando se un dato DateTimeha valori predefiniti (corrispondenti a 0001-01-01T00:00:00.0000000). Come risponde questo alla domanda?
dbc

-3
DateTime temp;
try
{
    temp = Convert.ToDateTime(grd.Rows[e.RowIndex].Cells["dateg"].Value);
    grd.Rows[e.RowIndex].Cells["dateg"].Value = temp.ToString("yyyy/MM/dd");
}
catch 
{   
    MessageBox.Show("Sorry The date not valid", "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop,MessageBoxDefaultButton.Button1,MessageBoxOptions .RightAlign);
    grd.Rows[e.RowIndex].Cells["dateg"].Value = null;
}

1
Devi verificare la validità provando a catturare. Quindi puoi usare try catch per controllare tutti i tipi di variabili e rendere valide funzioni globali e controllare tutto nel tuo progetto. i migliori saluti ..... Ashraf khalifah
Ashraf Khalifah

-3
DateTime temp;
try
{
    temp = Convert.ToDateTime(date);
    date = temp.ToString("yyyy/MM/dd");
}
catch 
{
    MessageBox.Show("Sorry The date not valid", "Error", MessageBoxButtons.OK, MessageBoxIcon.Stop,MessageBoxDefaultButton.Button1,MessageBoxOptions .RightAlign);
    date = null;
}
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.