Mam datę i godzinę w łańcuchu o takim formacie:
"2011-03-21 13:26" //year-month-day hour:minute
Jak mogę to przeanalizować System.DateTime
?
Chcę użyć funkcji takich jak DateTime.Parse()
lub, DateTime.ParseExact()
jeśli to możliwe, aby móc ręcznie określić format daty.
Odpowiedzi:
DateTime.Parse()
spróbuje wymyślić format podanej daty i zwykle działa to dobrze. Jeśli możesz zagwarantować, że daty zawsze będą w podanym formacie, możesz użyćParseExact()
:(Należy jednak pamiętać, że zwykle bezpieczniej jest użyć jednej z metod TryParse na wypadek, gdyby data nie miała oczekiwanego formatu)
Upewnij się, że sprawdzasz niestandardowe ciągi formatujące datę i godzinę podczas tworzenia ciągu formatu, szczególnie zwracaj uwagę na liczbę liter i wielkości liter (np. „MM” i „mm” oznaczają bardzo różne rzeczy).
Innym przydatnym zasobem dla ciągów formatu C # jest formatowanie ciągów w języku C #
źródło
s
. Dlatego lepiej jest użyć TryParseExcact. W mojej odpowiedzi poniżej wskazałem dlaczego.Jak wyjaśnię później, zawsze preferowałbym metody
TryParse
iTryParseExact
. Ponieważ są trochę nieporęczne w użyciu, napisałem metodę rozszerzającą, która znacznie ułatwia analizowanie:W przeciwieństwie
Parse
,ParseExact
itd. To nie wyjątek, i pozwala sprawdzić poprzezif (dt.HasValue) { // continue processing } else { // do error handling }
czy konwersja powiodła się (w tym przypadku
dt
ma wartość, do której można uzyskać dostęp przezdt.Value
), czy nie (w tym przypadku jestnull
).Pozwala to nawet na używanie eleganckich skrótów, takich jak operator „Elvis”
?.
, na przykład:Tutaj możesz również użyć
year.HasValue
do sprawdzenia, czy konwersja się powiodła, a jeśli się nie powiodła,year
będzie zawieraćnull
, w przeciwnym razie część roku z daty. Nie ma żadnego wyjątku, jeśli konwersja nie powiodła się.Rozwiązanie: metoda rozszerzenia .ToDate ()
Wypróbuj w .NetFiddle
Trochę informacji o kodzie
Możesz się zastanawiać, dlaczego użyłem
InvariantCulture
wywołaniaTryParseExact
: ma to na celu wymuszenie na funkcji traktowania wzorców formatu zawsze w ten sam sposób (w przeciwnym razie na przykład „.” Może być interpretowane jako separator dziesiętny w języku angielskim, podczas gdy jest to separator grupy lub separator daty w Niemiecki). Przypomnijmy, że już kilka wierszy wcześniej przeszukiwaliśmy ciągi formatu opartego na kulturze, więc tutaj jest w porządku.Aktualizacja:
.ToDate()
(bez parametrów) teraz domyślnie wszystkie typowe wzorce daty / godziny bieżącej kultury wątku.Zauważ , że potrzebujemy
result
idt
razem, ponieważTryParseExact
nie pozwala na użycieDateTime?
, które zamierzamy zwrócić. W C # w wersji 7 możnaToDate
nieco uprościć funkcję w następujący sposób:lub jeśli wolisz jeszcze krócej:
w takim przypadku nie potrzebujesz tych dwóch deklaracji
DateTime? result = null;
iwDateTime dt;
ogóle - możesz to zrobić w jednej linii kodu. ( Jeśli wolisz, możesz również pisaćout DateTime dt
zamiastout var dt
tego).Mam uproszczony kod dalej za pomocą
params
słowa kluczowego: Teraz już nie potrzebujesz 2 nd przeciążona metoda dłużej.Przykład użycia
Jak widać, ten przykład po prostu pyta,
dt.HasValue
czy konwersja się powiodła, czy nie. Jako dodatkowy bonus TryParseExact pozwala określić ścisłe,DateTimeStyles
dzięki czemu wiesz dokładnie, czy prawidłowy ciąg daty / czasu został przekazany, czy nie.Więcej przykładów użycia
Przeciążona funkcja umożliwia przekazanie tablicy prawidłowych formatów używanych do analizowania / konwertowania dat, jak pokazano tutaj (
TryParseExact
bezpośrednio to obsługuje), np.Jeśli masz tylko kilka wzorów szablonów, możesz również napisać:
Zaawansowane przykłady
Możesz użyć
??
operatora, aby domyślnie ustawić format awaryjny, npW takim przypadku
.ToDate()
użyje typowych formatów dat kultury lokalnej, a jeśli wszystkie te zawiodą, spróbuje użyć standardowego formatu ISO"yyyy-MM-dd HH:mm:ss"
jako rezerwy. W ten sposób funkcja rozszerzenia umożliwia łatwe łączenie różnych formatów rezerwowych.Możesz nawet użyć rozszerzenia w LINQ, wypróbuj to (jest w .NetFiddle powyżej):
który konwertuje daty w tablicy w locie przy użyciu wzorców i zrzuca je do konsoli.
Trochę informacji o TryParseExact
Na koniec kilka komentarzy na temat tła (tj. Powodu, dla którego napisałem to w ten sposób):
Preferuję TryParseExact w tej metodzie rozszerzenia, ponieważ unikasz obsługi wyjątków - możesz przeczytać w artykule Erica Lipperta o wyjątkach, dlaczego warto używać TryParse zamiast Parse, cytuję go na ten temat: 2)
Tak, ale
TryParse
iTryParseExact
oba są nadal o wiele mniej niż wygodne w użyciu: zmuszają cię do użycia niezainicjowanej zmiennej jakoout
parametru, który nie może mieć wartości null, a podczas konwersji musisz ocenić wartość logiczną zwracaną - albo masz aby użyćif
instrukcji natychmiast lub musisz zapisać zwracaną wartość w dodatkowej zmiennej boolowskiej, abyś mógł sprawdzić później. Nie możesz po prostu użyć zmiennej docelowej, nie wiedząc, czy konwersja się powiodła, czy nie.W większości przypadków chcesz tylko wiedzieć, czy konwersja się powiodła, czy nie (i oczywiście wartość, jeśli się powiodła) , więc zmienna docelowa dopuszczająca wartość null, która przechowuje wszystkie informacje, byłaby pożądana i znacznie bardziej elegancka - ponieważ cała informacja jest po prostu przechowywane w jednym miejscu: jest spójne i łatwe w użyciu oraz znacznie mniej podatne na błędy.
Metoda rozszerzenia, którą napisałem, robi dokładnie to (pokazuje również, jaki rodzaj kodu musiałbyś napisać za każdym razem, jeśli nie zamierzasz go używać).
Uważam, że zaletą
.ToDate(strDateFormat)
jest to, że wygląda prosto iDateTime.Parse
przejrzyście - tak prosto, jak miał być oryginał - ale z możliwością sprawdzenia, czy konwersja się powiodła, i bez rzucania wyjątków.1) Chodzi tutaj o to, że obsługa wyjątków (tj.
try { ... } catch(Exception ex) { ...}
Blok) - która jest konieczna, gdy używasz Parse, ponieważ zgłosi wyjątek, jeśli analizowany jest nieprawidłowy ciąg - jest nie tylko niepotrzebna w tym przypadku, ale także irytująca, i komplikowanie kodu. TryParse unika tego wszystkiego, ponieważ pokazuje przykładowy kod, który podałem.2) Eric Lippert jest znanym pracownikiem StackOverflow i przez kilka lat pracował w firmie Microsoft jako główny programista w zespole kompilatora C #.
źródło
Sprawdź ten link, aby uzyskać inne ciągi formatu!
źródło
DateTime.Parse () powinna działać dobrze dla tego formatu ciągu. Odniesienie:
http://msdn.microsoft.com/en-us/library/1k1skd40.aspx#Y1240
Czy generuje dla Ciebie wyjątek FormatException?
źródło
Umieść wartość ciągu czytelnego dla człowieka w .NET DateTime za pomocą następującego kodu:
źródło
Prosta i prosta odpowiedź ->
źródło
Możesz również użyć XmlConvert.ToDateString
Dobrze jest określić rodzaj daty, kod to:
Więcej szczegółów na temat różnych opcji analizowania http://amir-shenodua.blogspot.ie/2017/06/datetime-parsing-in-net.html
źródło
Wypróbuj poniższy kod
źródło