2010-07-23 14 views
13

Mientras que luchan con problemas de formato DateTime.ParseExact, me decidieron alimentar a la ParseExact hacia fuera puesto de DateTime.ToString(), así:¿Por qué no puede DateTime.ParseExact analizar el resultado de DateTime?

DateTime date2 = new DateTime(1962, 1, 27); 
string[] expectedFormats = { "G", "g", "f", "F", "D", "d", "M/d/yyy", "MM/dd/yyy", "MM-dd-yyy", "MMM dd, yyy", "MMM dd yyy", "MMMM dd, yyy", "MMMM dd yyy" }; 
bool parsed = false; 

foreach (string fmt in expectedFormats) 
{ 
    try 
    { 
     DateTime dtDateTime = DateTime.ParseExact(date2.ToString(fmt), fmt, new CultureInfo("en-US")); 
     parsed = true; 
    } 
    catch (Exception) 
    { 
     parsed = false; 
    } 

    Console.WriteLine("[{0}] {1}", parsed,date2.ToString(fmt)); 
} 

Ésta es la salida:

[True] 1/27/1962 12:00:00 AM 
[True] 1/27/1962 12:00 AM 
[True] Saturday, January 27, 1962 12:00 AM 
[True] Saturday, January 27, 1962 12:00:00 AM 
[True] Saturday, January 27, 1962 
[True] 1/27/1962 
[False] 1/27/1962 
[False] 01/27/1962 
[False] 01-27-1962 
[False] Jan 27, 1962 
[False] Jan 27 1962 
[False] January 27, 1962 
[False] January 27 1962 

Qué hacer Tengo que hacerlo para que ParseExact analice las cadenas de formato personalizadas. ¿Me equivoco al esperar que DateTime pueda ingerir su propia salida basándose en la misma cadena de formato?

+1

No es la causa del error, pero para información: estás pasando a una cultura específica para analizar, pero utilizando la referencia cultural predeterminada para ToString.Esto en sí mismo causaría problemas debido a la configuración regional. Pero lo he probado, y este no es el * único * problema. –

+0

@Marc: Lo probé pasando la misma cultura en ambos métodos también. También probé 'CultureInfo.InvariantCulture' para kicks-n-grins en vano. –

Respuesta

11

Esto demuestra claramente que DateTime.ParseExact no es seguro de ida y vuelta con Datetime.ToString. No estoy seguro de que esto sea una gran respuesta, pero el problema está definitivamente relacionado con el formato de año de 3 dígitos yyy. Desde 1962 no se puede representar en 3 dígitos ToString está obligado a usar 4 dígitos. Aparentemente ParseExact no es lo suficientemente inteligente como para revertir esa lógica y en su lugar está buscando exactamente 3 dígitos. La solución consiste en utilizar yyyy en lugar de yyy. Me gustaría enviar esto como un error al sitio web Microsoft Connect y ver qué ocurre.

+0

Tienes razón. yyyy soluciona el problema. –

+0

¡De hecho lo hace! ¡Gracias! –

0

Me estoy sorprendido de ver esto, pero la documentación en MSDN dice:

Puede especificar uno de los especificadores de formato de fecha y hora estándar o una combinación limitada de la fecha y hora personalizado especificador de formato

http://msdn.microsoft.com/en-us/library/2h3syy57.aspx

actualización

Puede usar la solución alternativa mencionada en la respuesta anterior.

0

Tomé su código, y cambiar "yyy" por "yyyy" es suficiente para devolver "VERDADERO" para todos (primero reproduje los "FALSOS" antes de realizar cambios).

La documentación en MSDN no está clara, pero sí enfatiza la necesidad de especificar el ancho total de todos los componentes (por ejemplo aaaa en lugar de yyy) sin la referencia cultural de todos:

http://msdn.microsoft.com/en-us/library/w2sa9yss.aspx

Si el formato es un patrón de formato personalizado que no incluye separadores de fecha u hora (como "aaaamMMdd HHmm"), utilice el cultivo invariable para el parámetro de proveedor y la forma más amplia de cada especificador de formato personalizado. Por ejemplo, si desea especificar horas en el patrón de formato, especifique la forma más amplia, "HH", en lugar de la forma más estrecha, "H".

+0

Los espacios, guiones y barras son separadores de fecha/hora. – Powerlord

+1

Yo también lo vi. Pero el código de ejemplo de Greg usa caracteres separadores, por lo que esta cláusula parece no aplicarse. Sin embargo, es buena información para señalar. –

+0

Estoy de acuerdo con ustedes en que la redacción en MSDN sugiere que los separadores de fecha y hora son el factor crucial, pero ejecutar el código yo mismo con "yyyy" resuelve el problema. –

Cuestiones relacionadas