Problema de DateTime.TryParse con fechas de formato aaaa-dd-MM

82

Tengo la siguiente fecha en formato de cadena "2011-29-01 12:00 am". Ahora estoy tratando de convertir eso al formato de fecha y hora con el siguiente código:

DateTime.TryParse(dateTime, out dt); 

Pero siempre recibo dt como {1/1/0001 12:00:00 AM}, ¿puede decirme por qué? y cómo puedo convertir esa cadena a la fecha.

EDITAR: Acabo de ver a todos mencionados para usar el argumento de formato. Mencionaré ahora que no puedo usar el parámetro de formato ya que tengo alguna configuración para seleccionar el formato de fecha personalizado que desea el usuario, y según ese usuario puede obtener la fecha en el cuadro de texto en ese formato automáticamente a través de jQuery datepicker.

Rocky Singh
fuente
4
Por cierto, puede determinar si la conversión falló al verificar el valor de retorno de TryParse. Eso es bool success = DateTime.TryParse(...);.
Jim Mischel

Respuestas:

184

Esto debería funcionar según su ejemplo "2011-29-01 12:00 am"

DateTime dt;
DateTime.TryParseExact(dateTime, 
                       "yyyy-dd-MM hh:mm tt", 
                       CultureInfo.InvariantCulture, 
                       DateTimeStyles.None, 
                       out dt);
Vidrio roto
fuente
8
Golpéame. Si conoce el formato de su cadena de entrada, virtualmente siempre debería usar los métodos TryParseExact / ParseExact.
Euro Micelli
bien, entonces mi formato de fecha es similar al del ejemplo, pero si el valor del día o mes es de un solo dígito, entonces el analizador DateTime arrojará un error, porque busca dos dígitos cuando solo hay uno. ¿Qué sugeriría en este escenario?
Ciaran Gallagher
11
Para responder a mi propia pregunta, en este caso, si usa un solo carácter en el formato, funciona tanto para fechas de caracteres simples como dobles. por ejemplo, d / m / aaaa funciona para el 13/11/2012
Ciaran Gallagher
@BrokenGlass esto no me está funcionando ¿Pueden ayudarme con esto?
Meena
2
@CiaranGallagher Solo un pequeño comentario, la fecha en su comentario debe usar una M grande (d / M / aaaa)
Yusril Maulidan Raji
14

Necesitas usar el ParseExactmétodo . Esto toma una cadena como segundo argumento que especifica el formato en el que se encuentra la fecha y hora, por ejemplo:

// Parse date and time with custom specifier.
dateString = "2011-29-01 12:00 am";
format = "yyyy-dd-MM h:mm tt";
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 el usuario puede especificar un formato en la interfaz de usuario, entonces debe traducirlo a una cadena que pueda pasar a este método. Puede hacerlo por cualquiera de permitir que el usuario introduzca la cadena de formato directamente - aunque esto significa que la conversión es más probable que falle a medida que se introduce una cadena de formato no válido - o tener un cuadro combinado que les presenta las posibles opciones y le configure las cadenas de formato para estas opciones.

Si es probable que la entrada sea incorrecta (la entrada del usuario, por ejemplo), sería mejor usar en TryParseExactlugar de usar excepciones para manejar el caso de error:

// Parse date and time with custom specifier.
dateString = "2011-29-01 12:00 am";
format = "yyyy-dd-MM h:mm tt";
DateTime result;
if (DateTime.TryParseExact(dateString, format, provider, DateTimeStyles.None, out result))
{
   Console.WriteLine("{0} converts to {1}.", dateString, result.ToString());
}
else
{
   Console.WriteLine("{0} is not in the correct format.", dateString);
}

Una mejor alternativa podría ser no presentarle al usuario una opción de formatos de fecha, sino usar la sobrecarga que toma una variedad de formatos :

// A list of possible American date formats - swap M and d for European formats
string[] formats= {"M/d/yyyy h:mm:ss tt", "M/d/yyyy h:mm tt", 
                   "MM/dd/yyyy hh:mm:ss", "M/d/yyyy h:mm:ss", 
                   "M/d/yyyy hh:mm tt", "M/d/yyyy hh tt", 
                   "M/d/yyyy h:mm", "M/d/yyyy h:mm", 
                   "MM/dd/yyyy hh:mm", "M/dd/yyyy hh:mm",
                   "MM/d/yyyy HH:mm:ss.ffffff" };
string dateString; // The string the date gets read into

try
{
    dateValue = DateTime.ParseExact(dateString, formats, 
                                    new CultureInfo("en-US"), 
                                    DateTimeStyles.None);
    Console.WriteLine("Converted '{0}' to {1}.", dateString, dateValue);
}
catch (FormatException)
{
    Console.WriteLine("Unable to convert '{0}' to a date.", dateString);
}                                               

Si lee los posibles formatos de un archivo de configuración o una base de datos, puede agregarlos a medida que encuentre las diferentes formas en que las personas desean ingresar fechas.

ChrisF
fuente
5

Intente usar el método TryParseExact seguro

DateTime temp;
string   date = "2011-29-01 12:00 am";

DateTime.TryParseExact(date, "yyyy-dd-MM hh:mm tt", CultureInfo.InvariantCulture, DateTimeStyles.None, out temp);
KateA
fuente
4

Desde DateTime en msdn:

Tipo: System.DateTime% Cuando este método regresa, contiene el valor de DateTime equivalente a la fecha y hora contenidas en s, si la conversión tuvo éxito, o MinValue si la conversión falló . La conversión falla si el parámetro s es nulo, es una cadena vacía ("") o no contiene una representación de cadena válida de una fecha y hora. Este parametro se pasa sin inicializar.

En su lugar, utilice parseexact con la cadena de formato "yyyy-dd-MM hh:mm tt".

RedDeckWins
fuente
3

Eso funciona:

DateTime dt = DateTime.ParseExact("2011-29-01 12:00 am", "yyyy-dd-MM hh:mm tt", System.Globalization.CultureInfo.InvariantCulture);
Lucas S.
fuente
1
DateTime dt = DateTime.ParseExact("11-22-2012 12:00 am", "MM-dd-yyyy hh:mm tt", System.Globalization.CultureInfo.InvariantCulture);
Hridayeshwar
fuente
0

Si le da al usuario la oportunidad de cambiar el formato de fecha / hora, entonces tendrá que crear una cadena de formato correspondiente para usar para el análisis. Si conoce los posibles formatos de fecha (es decir, el usuario tiene que seleccionar de una lista), entonces esto es mucho más fácil porque puede crear esas cadenas de formato en tiempo de compilación.

Si permite que el usuario realice un diseño de formato libre del formato de fecha / hora, tendrá que crear las DateTimecadenas de formato correspondientes en tiempo de ejecución.

Jim Mischel
fuente
Así es, jim. Si dejas que el usuario haga un diseño de formato libre del formato de fecha / hora, entonces tendrás que crear las cadenas de formato DateTime correspondientes en tiempo de ejecución.
Pinal