Wydanie DateTime.TryParse z datami w formacie rrrr-dd-MM

84

Mam następującą datę w formacie ciągu „2011-29-01 12:00”. Teraz próbuję przekonwertować to na format daty i godziny za pomocą następującego kodu:

DateTime.TryParse(dateTime, out dt); 

Ale zawsze otrzymuję dt jako {1/1/0001 12:00:00 AM}. Czy możesz mi powiedzieć, dlaczego? i jak mogę przekonwertować ten ciąg na bieżąco.

EDYCJA: Właśnie widziałem, jak wszyscy wspomniani używają argumentu formatu. Wspomnę teraz, że nie mogę użyć parametru format, ponieważ mam pewne ustawienia, aby wybrać niestandardowy format daty, czego chce użytkownik, i na podstawie tego użytkownika jest w stanie automatycznie pobrać datę w polu tekstowym w tym formacie za pośrednictwem jQuery datepicker.

Rocky Singh
źródło
4
Przy okazji możesz określić, czy konwersja nie powiodła się, sprawdzając zwracaną wartość TryParse. To znaczy bool success = DateTime.TryParse(...);.
Jim Mischel

Odpowiedzi:

188

To powinno działać na podstawie Twojego przykładu „2011-29-01 12:00”

DateTime dt;
DateTime.TryParseExact(dateTime, 
                       "yyyy-dd-MM hh:mm tt", 
                       CultureInfo.InvariantCulture, 
                       DateTimeStyles.None, 
                       out dt);
Rozbite szkło
źródło
8
Pokonaj mnie. Jeśli znasz format ciągu wejściowego, praktycznie zawsze powinieneś używać metod TryParseExact / ParseExact.
Euro Micelli
okej, więc mój format daty jest podobny do tego z przykładu, ale jeśli wartość dnia lub miesiąca jest jednocyfrowa, parser DateTime zwróci błąd, ponieważ szukał dwóch cyfr, gdy jest tylko jedna. Co byś zasugerował w tym scenariuszu?
Ciaran Gallagher
11
Odpowiadając na moje własne pytanie, w tym przypadku, jeśli używasz jednego znaku w formacie, działa on zarówno dla dat jedno-, jak i dwuznakowych. np. d / m / yyyy działa w
Ciaran Gallagher
@BrokenGlass to nie działa dla mnie Czy możesz mi z tym pomóc
Meena
2
@CiaranGallagher Tylko mała uwaga, data w Twoim komentarzu powinna zawierać duże M (d / M / yyyy)
Yusril Maulidan Raji
14

Musisz użyć ParseExactmetody . Jako drugi argument przyjmuje ciąg znaków, który określa format daty i godziny, na przykład:

// Parse date and time with custom specifier.
dateString = "2011-29-01 12:00 am";
format = "yyyy-dd-MM h:mm tt";
try
{
   result = DateTime.ParseExact(dateString, format, provider);
   Console.WriteLine("{0} converts to {1}.", dateString, result.ToString());
}
catch (FormatException)
{
   Console.WriteLine("{0} is not in the correct format.", dateString);
}

Jeśli użytkownik może określić format w interfejsie użytkownika, musisz przetłumaczyć go na ciąg, który możesz przekazać do tej metody. Można to zrobić albo poprzez umożliwienie użytkownikowi wprowadzić bezpośrednio ciąg formatu - choć oznacza to, że konwersja jest bardziej podatne na uszkodzenia, ponieważ będzie wprowadzić nieprawidłowy ciąg formatu - lub posiadające pole kombi, który przedstawia je z możliwych wyborów, a ty ustaw ciągi formatujące dla tych wyborów.

Jeśli prawdopodobne jest, że dane wejściowe będą nieprawidłowe (na przykład dane wejściowe użytkownika), lepiej byłoby użyć TryParseExactzamiast używać wyjątków do obsługi przypadku błędu:

// Parse date and time with custom specifier.
dateString = "2011-29-01 12:00 am";
format = "yyyy-dd-MM h:mm tt";
DateTime result;
if (DateTime.TryParseExact(dateString, format, provider, DateTimeStyles.None, out result))
{
   Console.WriteLine("{0} converts to {1}.", dateString, result.ToString());
}
else
{
   Console.WriteLine("{0} is not in the correct format.", dateString);
}

Lepszą alternatywą może być nie prezentowanie użytkownikowi wyboru formatów daty, ale użycie przeciążenia, które pobiera tablicę formatów :

// A list of possible American date formats - swap M and d for European formats
string[] formats= {"M/d/yyyy h:mm:ss tt", "M/d/yyyy h:mm tt", 
                   "MM/dd/yyyy hh:mm:ss", "M/d/yyyy h:mm:ss", 
                   "M/d/yyyy hh:mm tt", "M/d/yyyy hh tt", 
                   "M/d/yyyy h:mm", "M/d/yyyy h:mm", 
                   "MM/dd/yyyy hh:mm", "M/dd/yyyy hh:mm",
                   "MM/d/yyyy HH:mm:ss.ffffff" };
string dateString; // The string the date gets read into

try
{
    dateValue = DateTime.ParseExact(dateString, formats, 
                                    new CultureInfo("en-US"), 
                                    DateTimeStyles.None);
    Console.WriteLine("Converted '{0}' to {1}.", dateString, dateValue);
}
catch (FormatException)
{
    Console.WriteLine("Unable to convert '{0}' to a date.", dateString);
}                                               

Jeśli odczytujesz możliwe formaty z pliku konfiguracyjnego lub bazy danych, możesz je dodać, gdy napotkasz różne sposoby wprowadzania dat.

ChrisF
źródło
5

Spróbuj użyć bezpiecznej metody TryParseExact

DateTime temp;
string   date = "2011-29-01 12:00 am";

DateTime.TryParseExact(date, "yyyy-dd-MM hh:mm tt", CultureInfo.InvariantCulture, DateTimeStyles.None, out temp);
KateA
źródło
4

Od DateTime na msdn:

Typ: System.DateTime% Gdy ta metoda zwraca, zawiera wartość DateTime odpowiadającą dacie i godzinie zawartej w s, jeśli konwersja się powiodła, lub MinValue, jeśli konwersja nie powiodła się . Konwersja nie powiedzie się, jeśli parametr s ma wartość null, jest ciągiem pustym („”) lub nie zawiera prawidłowej reprezentacji daty i godziny w postaci ciągu. Ten parametr jest przekazywany bez zainicjowania.

Zamiast tego użyj parseexact z ciągiem formatu "yyyy-dd-MM hh:mm tt".

RedDeckWins
źródło
3

To działa:

DateTime dt = DateTime.ParseExact("2011-29-01 12:00 am", "yyyy-dd-MM hh:mm tt", System.Globalization.CultureInfo.InvariantCulture);
Lucas S.
źródło
1
DateTime dt = DateTime.ParseExact("11-22-2012 12:00 am", "MM-dd-yyyy hh:mm tt", System.Globalization.CultureInfo.InvariantCulture);
Hridayeshwar
źródło
0

Jeśli dasz użytkownikowi możliwość zmiany formatu daty / godziny, będziesz musiał utworzyć odpowiedni ciąg formatu, który będzie używany do analizowania. Jeśli znasz możliwe formaty daty (tj. Użytkownik musi wybrać z listy), jest to znacznie łatwiejsze, ponieważ możesz utworzyć te ciągi formatujące w czasie kompilacji.

Jeśli pozwolisz użytkownikowi zaprojektować format daty / czasu w dowolnym formacie, będziesz musiał utworzyć odpowiednie DateTimeciągi formatu w czasie wykonywania.

Jim Mischel
źródło
Zgadza się jim Jeśli pozwolisz użytkownikowi zaprojektować format daty / godziny w dowolnym formacie, będziesz musiał utworzyć odpowiednie ciągi formatu DateTime w czasie wykonywania.
Pinal