2010-07-23 12 views
13

Mentre alle prese con problemi di formattazione DateTime.ParseExact, ho deciso di alimentare il ParseExact fuori messo da DateTime.ToString(), in questo modo:Perché DateTime.ParseExact non può analizzare l'output 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)); 
} 

Questa è l'uscita:

[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 

Cosa fare Devo fare in modo che ParseExact analizzerà le stringhe di formato personalizzate? Mi sbaglio se DateTime sarà in grado di ingerire il proprio output basato sulla stessa stringa di formato?

+1

E non è la causa del bug, ma per info: si passa una cultura specifica per analizzare, ma utilizzando la lingua predefinita per ToString.Questo stesso causerebbe problemi a causa delle impostazioni locali. Ma ho provato, e questo non è il * solo * problema. –

+0

@Marc: l'ho testato anche passando la stessa cultura in entrambi i metodi. Ho anche provato "CultureInfo.InvariantCulture" per kick-n-grins inutilmente. –

risposta

11

Ciò dimostra chiaramente che DateTime.ParseExact non è sicuro per andata e ritorno con Datetime.ToString. Non sono sicuro che questa sia una gran parte della risposta, ma il problema è sicuramente correlato al formato dell'anno a 3 cifre yyy. Dal 1962 non può essere rappresentato in 3 cifre ToString è costretto a utilizzare 4 cifre. Apparentemente ParseExact non è abbastanza intelligente per invertire quella logica e invece sta cercando esattamente 3 cifre. La soluzione alternativa è utilizzare yyyy anziché yyy. Lo invierò come bug al sito web Microsoft Connect e vedremo cosa ne verrà fuori.

+0

Hai ragione. yyyy risolve il problema. –

+0

Effettivamente lo fa! Grazie! –

0

mi sono sorpreso di vedere questo, ma la documentazione in MSDN dice:

È possibile specificare uno dei formato data e ora specificatori standard o una combinazione limitata della data e dell'ora di formato personalizzato

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

Aggiornamento

È possibile utilizzare la soluzione alternativa menzionata nella risposta precedente.

0

Ho preso il tuo codice e cambiare "yyy" in "yyyy" è sufficiente per restituire "TRUE" per tutti (avendo prima riprodotto i "FALSE" prima di apportare eventuali modifiche).

La documentazione in MSDN è chiaro, ma non sottolineare la necessità di specificare la larghezza di ogni componente (ad es aaaa anziché yyy) senza la cultura invarianti:

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

Se formato è un modello di formato personalizzato che non include separatori di data o ora (come "yyyyMMdd HHmm"), usa la cultura invariante per il parametro provider e la forma più ampia di ogni identificatore di formato personalizzato. Ad esempio, se si desidera specificare ore nel modello di formato, specificare la forma più ampia, "HH", anziché la forma più stretta, "H".

+0

Spazi, trattini e barre sono separatori di data e ora. – Powerlord

+1

L'ho visto anche io. Ma il codice di esempio di Greg usa caratteri separatori, quindi questa clausola sembra non essere applicata. È comunque una buona informazione da sottolineare. –

+0

Concordo con voi ragazzi sul fatto che la formulazione di MSDN suggerisce che i separatori di data/ora sono il fattore cruciale, ma l'esecuzione del codice me stesso utilizzando "yyyy" risolve il problema. –

Problemi correlati