Valores decimales reconocidos como DateTime en lugar de devolver false desde DateTime.Parse

9

Necesito realizar una verificación basada en un valor de cadena, ya sea una fecha o decimal, pero el análisis de fecha siempre devuelve verdadero para decimal.

string val = "3.5";
DateTime oDate = DateTime.Parse(val);

Devuelve una fecha válida 3/5/2019.

¿Cómo validar la cadena para saber que es una fecha válida cuando no se conoce el formato de fecha?

Munawar
fuente
66
¿Verifica el decimal primero? O úselo DateTime.ParseExactsi sabe qué formatos puede / debería tomar
Un amigo
3
Puede usar TryParseExacty especificar formatos de fecha válidos.
juharr
55
De hecho, DateTime.Parseintenta múltiples patrones. Si solo desea reconocer los específicos, intente analizarlos específicamente.
Jon Skeet
1
¿Responde esto a tu pregunta? Compruebe si una cadena es una fecha válida utilizando DateTime
Joost K

Respuestas:

3

"¿Cómo validar una cadena para saber que es una fecha válida?"

El problema es que "3.5" se considera una fecha válida (y también un decimal).

Si desea que el tipo decimal siempre "gane" (es decir, no quiere isDatey isDecimalque ambos sean true), incluya una verificación decimal en su validación.

Una forma de hacerlo es usar los TryParsemétodos (que devuelven un boolsi una cadena se puede analizar al tipo, y que establece un outparámetro al valor convertido) para determinar si la cadena se puede convertir a un tipo, por ejemplo:

string val = "3.5";

// temp variables to hold parsed values
DateTime tmpDate;
decimal tmpDec;
int tmpInt;

var isDecimal = decimal.TryParse(val, out tmpDec);
var isInteger = int.TryParse(val, out tmpInt);

// When checking if it's a DateTime, make sure it's not also a decimal
var isDate = !isDecimal && DateTime.TryParse(val, out tmpDate);
Rufus L
fuente
Ya lo había intentado, pero 3.5 es una fecha válida y un decimal válido, por lo que no ayuda en absoluto.
Munawar
1
En el código anterior, isDatees falseporque incluye un cheque para isDecimal. ¿No es eso lo que estabas pidiendo?
Rufus L
2
@Munawar - "3.5 es una fecha válida y un decimal válido" exactamente. Si, como humanos, se nos presenta esa cadena y ningún otro contexto, no sabemos si fue una fecha, un decimal o una posible otra cosa . No se puede esperar que una computadora obtenga mágicamente una respuesta.
Damien_The_Unbeliever
Sí, esta respuesta es específica del problema y resuelve mi problema, aunque ParseExact se ajustará mejor si se conocen formatos.
Munawar
Todavía tiene el problema cuando el formato de fecha es "12122019"
Athanasios Kataras
6

Consulte la documentación oficial en ParseExact

Si conoce la representación exacta, puede hacer algo como esto:

  format = "ddd dd MMM yyyy h:mm tt zzz";
  try {
     result = DateTime.ParseExact(dateString, format, provider);
     Console.WriteLine("{0} converts to {1}.", dateString, result.ToString());
  }
  catch (FormatException) {
     Console.WriteLine("{0} is not in the correct format.", dateString);
  }

Si no lo sabes, entonces estás atrapado en las convenciones culturales.

Analiza una cadena de fecha y hora utilizando las convenciones de una cultura específica. Sobrecarga Parse (String, IFormatProvider) (ver Convenciones culturales y de análisis)

Athanasios Kataras
fuente
Se desconoce el formato, puede basarse en las preferencias del usuario.
Munawar
1
@Munawar, ¿cómo distinguirá entre 1/3/2019 y 3/1/2019 en esa situación?
Blaise
@Athanasios, la aplicación se utiliza para diferentes regiones y fechas almacenadas encriptadas. desde entonces, el usuario puede cambiar los formatos de fecha, así que no quiera meterse con la aplicación de formatos específicos, aunque ParseExact es el más adecuado si se conoce el formato.
Munawar