Comment valider un DateTime en C #?


118

Je doute que je sois le seul à avoir proposé cette solution, mais si vous en avez une meilleure, veuillez la poster ici. Je veux simplement laisser cette question ici pour que d'autres puissent la rechercher plus tard.

J'avais besoin de dire si une date valide avait été entrée dans une zone de texte et c'est le code que j'ai trouvé. Je tire ceci lorsque le focus quitte la zone de texte.

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

1
<sarcasm> à en juger par les réponses, je pense que je devrais utiliser TryParse </sarcasm> Merci pour les bonnes réponses les gars. Je n'avais même pas pensé à TryParse
Matt

2
Un exemple d'une question facile à google qui si quelqu'un posait aujourd'hui serait injustement fermée pour n'avoir "pas assez de recherche".
live-love

1
voici un moyen simple de le faire sans utiliser de fonctions spéciales: < stackoverflow.com/questions/14917203/... >
Zameer


2
Travailler avec DateTimes est toujours une douleur dans la basse. Merci
Gonzo345

Réponses:


269
DateTime.TryParse

Je crois que c'est plus rapide et cela signifie que vous n'avez pas à utiliser de vilains essais / captures :)

par exemple

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

2
Corrigez-moi si je me trompe, mais en C # (par opposition à, disons, JavaScript), une branche if / else ne nécessite-t-elle pas des accolades? Ne vous méprenez pas, je n'essaie pas de scruter, c'est une réponse fantastique et je la +1 parce que cela m'a aidé, mais je pensais simplement que vous ne savez jamais à quel point les futurs utilisateurs sont lorsqu'ils consultent des réponses déjà publiées, ceci pourrait les confondre. Bien sûr, si vous rencontrez des problèmes avec les accolades en C #, cette question serait le moindre de vos soucis ...
VoidKing

2
@VoidKing Vous avez raison sur les accolades, mais si vous n'avez qu'une seule instruction dans ce bloc, vous n'avez pas à les utiliser. Cela s'applique également à d'autres langues, mais je peux voir comment cela peut être trompeur pour les nouveaux codeurs.
D.Galvez

2
@ D.Galvez Excusez ma venue tardive à la fête, mais est-ce une bonne pratique d'inclure les crochets même s'il n'y a qu'une seule déclaration? Cela pourrait simplement être une situation où les préférences personnelles sont les plus importantes - et dans ce cas, je trouve que les inclure est assez agréable simplement pour la lisibilité et la cohérence.
Nick

2
Je ne savais pas, il y a 6 ans, qu'un tel débat sur les crochets aurait lieu.
qui

Il est possible de raccourcir l'initialisation des variables avec if(DateTime.TryParse(startDateTextBox.Text, out var temp)):)
Alexandre Daubricourt

61

N'utilisez pas d'exceptions pour le contrôle de flux. Utilisez DateTime.TryParse et DateTime.TryParseExact . Personnellement, je préfère TryParseExact avec un format spécifique, mais je suppose qu'il y a des moments où TryParse est meilleur. Exemple d'utilisation basé sur votre code d'origine:

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

Raisons de préférer cette approche:

  • Code plus clair (il dit ce qu'il veut faire)
  • Meilleures performances que d'attraper et d'avaler des exceptions
  • Cela n'attrape pas les exceptions de manière inappropriée - par exemple OutOfMemoryException, ThreadInterruptedException. (Votre code actuel pourrait être corrigé pour éviter cela en interceptant simplement l'exception pertinente, mais utiliser TryParse serait toujours mieux.)

24

Voici une autre variante de la solution qui renvoie true si la chaîne peut être convertie en DateTimetype et false dans le cas contraire.

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

3
Bienvenue dans StackOverflow! Veuillez regarder les réponses qui ont déjà été fournies, en particulier lorsque vous répondez à une question qui date de plus de trois ans et qui a reçu une réponse satisfaisante. Votre réponse a déjà été couverte par les répondants précédents.
Bob Kaufman



3

Un problème avec l'utilisation DateTime.TryParseest qu'il ne prend pas en charge le cas d'utilisation très courant de saisie de données de dates saisies sans séparateurs, par exemple 011508.

Voici un exemple de la façon de soutenir cela. (Ceci provient d'un framework que je construis, donc sa signature est un peu bizarre, mais la logique de base devrait être utilisable):

    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;
            }
        }

    }

Dans mon cas, je ne m'inquiète pas pour les séparateurs, car j'utilise une zone de texte masquée, mais je peux voir à quel point cela serait utile dans d'autres situations que je pourrais rencontrer avec cette application.
Matt

Quelle est la raison d'utiliser la chaîne DateTime sans séparateurs?
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;
    }

// suppose que la chaîne d'entrée est au format de date court.
Par exemple, "2013/7/5" renvoie vrai ou
"2013/2/31" renvoie faux.
http://forums.asp.net/t/1250332.aspx/1
// bool booleanValue = ValidateBirthday ("12:55"); renvoie faux


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

Toutes les réponses sont assez bonnes, mais si vous souhaitez utiliser une seule fonction, cela peut fonctionner.

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

1
Que diriez-vous de renvoyer le résultat de DateTime.TryParse () au lieu du bloc "if"? En outre, votre IDE se plaindrait de la température jamais utilisée, que vous pourriez déclarer directement dans l'appel de fonction comme "out DateTime temp".
Sergei Kovalenko

0

Vous pouvez également définir le DateTimeformat d'unCultureInfo

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
Bien que ce code puisse résoudre la question, inclure une explication sur comment et pourquoi cela résout le problème aiderait vraiment à améliorer la qualité de votre publication et entraînerait probablement plus de votes à la hausse. N'oubliez pas que vous répondez à la question des lecteurs à l'avenir, pas seulement à la personne qui la pose maintenant. Veuillez modifier votre réponse pour ajouter des explications et donner une indication des limites et des hypothèses applicables.
Brian

La question est de savoir comment valider un stringqui pourrait ou non contenir une DateTImevaleur. Vous vérifiez si une donnée DateTimea des valeurs par défaut (correspondant à 0001-01-01T00:00:00.0000000). Comment cela répond-il à la question?
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
Vous devez vérifier la validité par try catch. Vous pouvez donc utiliser try catch pour vérifier tous les types de variables et créer des fonctions globales valides et contrôler tout dans votre projet. Best regards ..... 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;
}
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.