2012-07-30 27 views
28

To trochę dziwne. Parsowanie pola tekstowego o prawidłowym czasie nie powiedzie się, jeśli staram się być precyzyjnym!Dlaczego TimeSpan.ParseExact nie działa

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); 

Drugi proces kończy się niepowodzeniem z wyjątkiem "Ciąg wejściowy nie był w poprawnym formacie." z DateTime.

+4

Może trzeba 'HH' zamiast' hh' (format 24 h) – V4Vendetta

+0

@ V4Vendetta: Należy post, który jako odpowiedź; to prawdopodobnie jest poprawne. –

+0

gdzie jest twoja randka? –

Odpowiedz

59

Z documentation:

Wszelkie inne zmiany znaczenia znaku w ciągu formatu, w tym biało spacja, jest interprete d jako specyfikator formatu niestandardowego. W większości przypadków obecność jakiejkolwiek innej nieodwzorowanej postaci powoduje wyjątek FormatException w postaci .

Istnieją dwa sposoby, aby umieścić dosłowny znak w ciągu formatu:

  • umieszczenie go w pojedynczych cudzysłowach (dosłowne ciąg ogranicznika).

  • Poprzedza go ukośnikiem odwrotnym ("\"), który jest interpretowany jako znak ucieczki. Oznacza to, że w języku C# ciąg formatu musi mieć wartość albo @ -quoted, albo literał musi być poprzedzony dodatkowym ukośnikiem odwrotnym.

.NET Framework nie definiuje gramatyki dla separatorów w czasie interwały. Oznacza to, że separatory między dniami i godzinami, godzin i minut, minut i sekund oraz sekund i ułamków sekundy muszą być traktowane jako literały znaków w ciągu formatującym.

Więc rozwiązaniem jest, aby określić ciąg formatu jak

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

Dobra odpowiedź, Jon - nigdy bym nie zdawał sobie sprawy, że 'ParseExact' ignoruje konwencję 12/24 godzinową z formaterami. –

+0

Tak to jest - nauczyłem się czegoś nowego już dziś! Dziwne, że Parse obsługuje separatory, ale ParseExact tego nie robi! – Quango

+0

Miałem nadzieję, że rozwiąże to mój problem związany z konwersją z 'string' na' TimeSpan' w łańcuchu Expression 'DataTable.Select()'. Jednak bez powodzenia. Zgłoszony błąd [tutaj] (https://connect.microsoft.com/VisualStudio/feedback/details/806804/datatable-select-nable-to-convert-string-to-timespan-net-framework-4). – Conrad

2

Wydaje się, że HH nie jest naprawdę dla TimeSpan

formacie Specyfikatory zwyczaj Okres nie zawierają placeholder symbole Separator, takie jak symbole, które oddzielne dni od godziny, godziny od minut lub sekund od ułamkowe sekundy. Zamiast tego te symbole muszą być zawarte w niestandardowym ciągu formatów jako ciągi literowe . Na przykład "dd.hh \: mm" definiuje kropkę (.) Jako separator między dniami i godzinami oraz dwukropek (:) jako separator między godzinami i minutami.

Stąd poprawny sposób byłoby jak Jon wspomniano uciec używając "\"Read More

Twój TimeSpan jest "17:23:24" który jest w formacie 24-godzinnym i powinien być analizowany przy użyciu formatu HH, a nie hh, który jest formatem 12-godzinnym.

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

Wyjazd the formats

+0

Nie dotyczy: specyfikator godzin, które nie są liczone jako część dni, to 'hh'. – Jon

+0

@Jon Co masz na myśli? – V4Vendetta

+1

Łączymy się z ciągami w formacie 'DateTime', które różnią się od ciągów w formacie' 'TimeSpan'' (http://msdn.microsoft.com/en-us/library/ee372287). – Jon

0

Spróbuj tego:

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

Dzięki za odpowiedź - patrz odpowiedź Jona na rzeczywisty problem. – Quango

8

Spróbuj tego:

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

Źródło: Standard TimeSpan Format Strings

+0

Dzięki za odpowiedź - nie zauważyłem formatu "c", który zajmuje się kwestią separatora: kolejna nowa rzecz nauczyli! – Quango

2

Jeśli nie chcą zajmować z różnicą w specyfikatorach formatu między TimeSpan.ParseExact i DateTime.ParseExact możesz ju st analizować swój ciąg jako DateTime i uzyskać składnik TimeOfDay jako TimeSpan jak ten:

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

Zobacz [tę odpowiedź] (https://stackoverflow.com/a/2552455/696391), aby dowiedzieć się, jak przejść w drugą stronę: formatowanie TimeSpan przy użyciu specyfikatorów formatu DateTime. – samgak