Validar un DateTime en C #

Dudo que sea el único que haya presentado esta solución, pero si tiene una mejor, publíquela aquí. Simplemente quiero dejar esta pregunta aquí para que yo y otros podamos buscarla más tarde.

Necesitaba decir si se había ingresado una fecha válida en un cuadro de texto y este es el código que se me ocurrió. Disparo esto cuando el foco deja el cuadro de texto.

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

 DateTime.TryParse 

Esto creo que es más rápido y significa que no tienes que usar feos bashs / capturas 🙂

p.ej

 DateTime temp; if(DateTime.TryParse(startDateTextBox.Text, out temp)) //yay else // :( 

No use excepciones para el control de flujo. Use DateTime.TryParse y DateTime.TryParseExact . Personalmente prefiero TryParseExact con un formato específico, pero creo que hay momentos en que TryParse es mejor. Ejemplo de uso basado en su código original:

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

Razones para preferir este enfoque:

  • Código más claro (dice lo que quiere hacer)
  • Mejor rendimiento que atrapar y tragar excepciones
  • Esto no detecta excepciones de forma inapropiada, por ejemplo, OutOfMemoryException, ThreadInterruptedException. (Su código actual podría corregirse para evitar esto simplemente capturando la excepción relevante, pero usar TryParse aún sería mejor).

Aquí hay otra variación de la solución que devuelve verdadero si la cadena se puede convertir a un tipo DateTime , y de lo contrario es falso.

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

¿Qué hay de usar TryParse ?

Un problema con el uso de DateTime.TryParse es que no admite el caso de uso de entrada de datos muy común de las fechas ingresadas sin separadores, por ejemplo 011508 .

Aquí hay un ejemplo de cómo apoyar esto. (Esto es de un marco que estoy construyendo, por lo que su firma es un poco extraña, pero la lógica del núcleo debería ser utilizable):

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

// supongamos que la cadena de entrada es un formato de fecha corta.
por ejemplo, “2013/7/5” devuelve verdadero o
“2013/2/31” devuelve falso.
http://forums.asp.net/t/1250332.aspx/1
// bool booleanValue = ValidateBirthday (“12:55”); devuelve falso