2012-07-30 6 views
28

Questo è un po 'strano. L'analisi di un campo di testo con un intervallo di tempo valido non riesce se cerco di essere preciso!Perché TimeSpan.ParseEx non funziona

const string tmp = "17:23:24"; 
//works 
var t1 = TimeSpan.Parse(tmp); 
//fails 
var t2 = TimeSpan.ParseExact(tmp, "hh:mm:ss", System.Globalization.CultureInfo.InvariantCulture); 

La seconda analisi non riesce con un'eccezione "La stringa di input non era in un formato corretto." da DateTime.

+4

Forse avete bisogno di 'HH' invece di' hh' (formato 24 ore) – V4Vendetta

+0

@ V4Vendetta: si dovrebbe post che come risposta; è probabile che sia corretto –

+0

dov'è il tuo appuntamento? –

risposta

59

Dal documentation:

Qualsiasi altro carattere di escape in una stringa di formato, tra cui un bianco- carattere spaziale, è interprete d come identificatore di formato personalizzato. Nella maggior parte dei casi in , la presenza di qualsiasi altro carattere senza caratteri di escape produce un valore FormatException .

Ci sono due modi per includere un carattere letterale in una stringa di formato:

  • racchiuderlo tra virgolette singole (il delimitatore di stringa letterale).

  • Preceduto da una barra rovesciata ("\"), che viene interpretata come un carattere di escape. Ciò significa che, in C#, la stringa di formato deve essere o essere quotata a @ oppure il carattere letterale deve essere preceduto da una barra rovesciata aggiuntiva .

Il .NET Framework non definisce una grammatica per i separatori in tempo intervalli. Ciò significa che i separatori tra i giorni e le ore, ore e minuti, minuti e secondi e secondi e le frazioni di un secondo devono essere tutti trattati come caratteri letterali in una stringa di formato.

Quindi, la soluzione è quella di specificare la stringa di formato come

TimeSpan.ParseExact(tmp, "hh\\:mm\\:ss", CultureInfo.InvariantCulture) 
+5

Bella risposta, Jon - Non mi ero mai reso conto che 'ParseExact' ignora la convenzione di 12/24 ore con i formattatori. –

+0

Così è - ho imparato qualcosa di nuovo oggi! Strano che Parse gestisca i separatori ma ParseExact no! – Quango

+0

Speravo che questo risolvesse il mio problema relativo alla conversione da 'stringa' a' TimeSpan' nella stringa Expression di 'DataTable.Select()'. Tuttavia, nessuna fortuna. Archiviato un bug [qui] (https://connect.microsoft.com/VisualStudio/feedback/details/806804/datatable-select-unable-to-convert-string-to-timespan-net-framework-4). – Conrad

2

Sembra che HH non è davvero per TimeSpan

Gli identificatori di formato TimeSpan personalizzate non includono segnaposto simboli di separazione, come ad esempio i simboli che giorni separati da ore, ore da minuti o secondi da secondi frazionari. Invece, questi simboli devono essere inclusi nella stringa del formato personalizzato come valori letterali stringa . Ad esempio, "dd.hh \: mm" definisce un punto (.) Come separatore tra giorni e ore e due punti (:) come separatore tra ore e minuti.

Quindi il modo corretto sarebbe come Jon menzionato sfuggire utilizzando "\"Read More

tuo TimeSpan è "17:23:24" che è nel formato di 24 ore e dovrebbe essere analizzato utilizzando il formato HH e non hh, che è per i formati di 12 ore.

TimeSpan.ParseExact(tmp, "HH:mm:ss",System.Globalization.CultureInfo.InvariantCulture); 

Partenza the formats

+0

Non pertinente: l'identificatore per le ore che non vengono conteggiate come parte dei giorni è 'hh'. – Jon

+0

@Jon Cosa intendi? – V4Vendetta

+1

Si sta eseguendo il collegamento alle stringhe di formato 'DateTime', che sono diverse dalle stringhe di formato [' TimeSpan'] (http://msdn.microsoft.com/en-us/library/ee372287). – Jon

0

Prova questa:

 var t2 = TimeSpan.ParseExact(tmp, "HH:mm:ss", System.Globalization.CultureInfo.InvariantCulture); 
+0

Grazie per la risposta - vedi la risposta di Jon per il problema reale. – Quango

8

Prova questa:

var t2 = TimeSpan.ParseExact(tmp, "c", System.Globalization.CultureInfo.InvariantCulture); 

Fonte: Standard TimeSpan Format Strings

+0

Grazie per la risposta - Non avevo notato il formato "c", che si occupa del problema del separatore: un'altra novità imparato! – Quango

2

Se non si vuole affrontare con la differenza di specificatori di formato tra TimeSpan.ParseExact e DateTime.ParseExact è possibile st analizzare la stringa come un DateTime e ottenere il componente TimeOfDay come TimeSpan come questo:

var t2 = DateTime.ParseExact(tmp, "hh:mm:ss", CultureInfo.InvariantCulture).TimeOfDay; 
+0

Vedere [questa risposta] (https://stackoverflow.com/a/2552455/696391) per come procedere nella direzione opposta: formattare un TimeSpan usando gli identificatori di formato DateTime. – samgak