Ciąg nie został rozpoznany jako prawidłowy „format daty i godziny” dd / MM / rrrr

172

Próbuję przekonwertować wartość w formacie ciągu na typ daty z formatem dd/MM/yyyy.

this.Text="22/11/2009";

DateTime date = DateTime.Parse(this.Text);

Jaki jest problem ? Ma drugie nadpisanie, o które prosi IFormatProvider. Co to jest? Czy muszę to również przekazać? Jeśli tak, jak go używać w tym przypadku?

Edytować

Jakie są różnice między Parsei ParseExact?

Edytuj 2

Obie odpowiedzi Slaksa i Sama pracują dla mnie, obecnie użytkownik podaje dane wejściowe, ale upewnię się, że są one prawidłowe za pomocą maskTextbox.

Która odpowiedź jest lepsza, biorąc pod uwagę wszystkie aspekty, takie jak bezpieczeństwo pisania, wydajność lub coś, na co masz ochotę

Shantanu Gupta
źródło
7
@Edit: Po to jest dokumentacja. msdn.microsoft.com/en-us/library/w2sa9yss.aspx
SLaks
2
ParseExact jest używany, gdy znasz dokładny format ciągu daty, Parse jest wtedy, gdy potrzebujesz czegoś, co może obsłużyć coś bardziej dynamicznego.
gingerbreadboy

Odpowiedzi:

255

Użyj DateTime.ParseExact.

this.Text="22/11/2009";

DateTime date = DateTime.ParseExact(this.Text, "dd/MM/yyyy", null);
Samuel Neff
źródło
8
Dlaczego musimy tutaj podać null?
Shantanu Gupta
3
Można wpisać „22/11/2009 12:00:00 AM” lub „22/11/2009”. Również kultura maszyny deweloperskiej może różnić się od kultury produkcji. Czy powyższy kod będzie działał bezproblemowo?
Rahatur
8
@Rahat, dokładna analiza nie zadziała, jeśli format nie pasuje. Powyższy wzorzec formatu jest dd/MM/yyyywięc ciągiem tekstowym zawierającym godzinę, który nie zostanie poprawnie przeanalizowany. Musisz albo usunąć czas, albo uwzględnić go we wzorcu formatu. Istnieje przeciążenie, ParseExactktóre akceptuje tablicę wzorców formatu i analizuje tekst, jeśli pasuje do któregokolwiek z nich.
Samuel Neff,
7
@SamuelNeff Dlaczego nie użyjesz CultureInfo.InvariantCulturezamiast obecnego, jeśli mimo wszystko definiujesz format?
Alvin Wong
3
@Toolkit Powodem jest to, że ukośniki w ciągu formatu nie są dosłownymi ukośnikami. Są one zastępowane ciągiem separatora daty w bieżącej kulturze. Tak więc zależy to od kultury w sposób, w jaki jest to napisane powyżej. Samuel Neff, spróbuj Thread.CurrentThread.CurrentCulture = new CultureInfo("da-DK");, to zepsuje twoje rozwiązanie. Aby to naprawić, użyj "dd'/'MM'/'yyyy"(chroniąc ukośniki pojedynczymi cudzysłowami) lub @"dd\/MM\/yyyy"(„uciekając” przed ukośnikiem odwrotnym ukośnikiem).
Jeppe Stig Nielsen
44

Musisz zadzwonić ParseExact, co analizuje datę, która dokładnie pasuje do podanego formatu.

Na przykład:

DateTime date = DateTime.ParseExact(this.Text, "dd/MM/yyyy", CultureInfo.InvariantCulture);

IFormatProviderParametr określa kulturę używać do analizowania datę.
O ile twój ciąg nie pochodzi od użytkownika, powinieneś przejść CultureInfo.InvariantCulture.
Jeśli ciąg pochodzi od użytkownika, należy przekazać CultureInfo.CurrentCulture, który użyje ustawień określonych przez użytkownika w Opcjach regionalnych w Panelu sterowania.

SLaks
źródło
2
@Slaks: CultureInfo.InvariantCulture nie jest dostępne w kodzie. Czy muszę używać przestrzeni nazw
Shantanu Gupta,
3
using System.Globalization;
SLaks
2
Możesz także kliknąć błąd prawym przyciskiem myszy i kliknąć rozwiąż, co spowoduje wstawienie brakującej przestrzeni nazw.
Inkey,
możesz także dwukrotnie kliknąć błąd i zobaczyć strzałkę w dół pokazującą powiązane przestrzenie nazw, których możesz użyć
Usman Younas
Spacje też się liczą, więc na przykład jeśli format ciągu to „MM / dd / rrrr HH: mm: ss” (uwaga - 2 spacje) - wtedy format ParseExact musi również zawierać spacje
Chris Halcrow
20

Analiza ciągu reprezentującego DateTime jest trudna, ponieważ różne kultury mają różne formaty dat. .Net jest świadomy tych formatów dat i pobiera je z bieżącej kultury ( System.Threading.Thread.CurrentThread.CurrentCulture.DateTimeFormat), gdy wywołujesz DateTime.Parse(this.Text);

Na przykład ciąg „22/11/2009” nie pasuje do ShortDatePattern dla Stanów Zjednoczonych (en-US), ale jest zgodny z Francją (fr-FR).

Teraz możesz wywołać DateTime.ParseExacti przekazać dokładny ciąg formatu, którego oczekujesz, lub możesz przekazać odpowiednią kulturę, DateTime.Parseaby przeanalizować datę.

Na przykład, to poprawnie przeanalizuje twoją datę:

DateTime.Parse( "22/11/2009", CultureInfo.CreateSpecificCulture("fr-FR") );

Oczywiście nie powinieneś losowo wybierać Francji, ale coś odpowiedniego dla swoich potrzeb.

Musisz dowiedzieć się, co System.Threading.Thread.CurrentThread.CurrentCulturejest ustawione i czy / dlaczego różni się od tego, czego oczekujesz.

Greg
źródło
Twoje rozwiązanie nie działa dla mnie, wyświetla błąd typu „Ciąg nie został rozpoznany jako prawidłowy DateTime”. i przekazuję następującą datę wprowadzenia: "13/06/17" do twojego rozwiązania, ale daje to błąd.Plz mi pomóż.
Ghanshyam Lakhani
16

Chociaż powyższe rozwiązania są skuteczne, możesz również zmodyfikować plik webconfig za pomocą następującego ...

<configuration>
   <system.web>
     <globalization culture="en-GB"/>
   </system.web>
</configuration>

Ref: Format daty i godziny różni się na maszynie lokalnej w porównaniu z maszyną produkcyjną

Amit Philips
źródło
1
Amit Philips, uratowałeś mi dzień. Próbowałem wszystkich możliwych rzeczy. I ta mała zmiana działa. Dzięki.
RNH
1
Tak, naprawdę jesteś synem Bożym.
The Furious Bear
10

Może być konieczne określenie kultury dla tego konkretnego formatu daty, jak w:

    Thread.CurrentThread.CurrentCulture = new CultureInfo("en-GB"); //dd/MM/yyyy

    this.Text="22/11/2009";

    DateTime date = DateTime.Parse(this.Text);

Więcej informacji można znaleźć tutaj:

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

Ricardo Sanchez
źródło
4

Po spędzeniu dużej ilości czasu rozwiązałem problem

 string strDate = PreocessDate(data);
 string[] dateString = strDate.Split('/');
 DateTime enter_date = Convert.ToDateTime(dateString[1]+"/"+dateString[0]+"/"+dateString[2]);
atik sarker
źródło
3

użyj tego, aby przekonwertować ciąg na datetime:

Datetime DT = DateTime.ParseExact(STRDATE,"dd/MM/yyyy",System.Globalization.CultureInfo.CurrentUICulture.DateTimeFormat)
AshifJM
źródło
3

W oparciu o to odniesienie zadziałało następne podejście:

// e.g. format = "dd/MM/yyyy", dateString = "10/07/2017" 
var formatInfo = new DateTimeFormatInfo()
{
     ShortDatePattern = format
};
date = Convert.ToDateTime(dateString, formatInfo);
Jesús Castro
źródło
2
private DateTime ConvertToDateTime(string strDateTime)
{
DateTime dtFinaldate; string sDateTime;
try { dtFinaldate = Convert.ToDateTime(strDateTime); }
catch (Exception e)
{
string[] sDate = strDateTime.Split('/');
sDateTime = sDate[1] + '/' + sDate[0] + '/' + sDate[2];
dtFinaldate = Convert.ToDateTime(sDateTime);
}
return dtFinaldate;
}
Bala Kumar
źródło
1

Tak jak ktoś powyżej powiedział, że możesz wysłać go jako parametr ciągu, ale musi on mieć następujący format: na przykład '20130121' i możesz go przekonwertować na ten format, pobierając go bezpośrednio z kontrolki. Więc otrzymasz go na przykład z pola tekstowego, takiego jak:

date = datetextbox.text; // date is going to be something like: "2013-01-21 12:00:00am"

aby przekonwertować go na: '20130121', użyjesz:

date = date.Substring(6, 4) + date.Substring(3, 2) + date.Substring(0, 2);

aby SQL mógł go przekonwertować i umieścić w bazie danych.

G Jeny Ramirez
źródło
0

Możesz również użyć

this.Text = "22112009";
DateTime newDateTime = new DateTime(Convert.ToInt32(this.Text.Substring(4, 4)), // Year
                                    Convert.ToInt32(this.Text.Substring(2,2)), // Month
                                    Convert.ToInt32(this.Text.Substring(0,2)));// Day
Serkan Hekimoglu
źródło
0

Pracował dla mnie poniższy kod:

DateTime date = DateTime.Parse(this.Text, CultureInfo.CreateSpecificCulture("fr-FR"));

Przestrzeń nazw

using System.Globalization;
Anjan Kant
źródło
-6

Zmień ręcznie:

string s = date.Substring(3, 2) +"/" + date.Substring(0, 2) + "/" + date.Substring(6, 4);

Od 22.11.2015 zostanie przekonwertowany 22.11.2015

sarta
źródło