2010-02-25 4 views
8

Ich erhalte eine String.FormatException, die versucht, eine Zeichenfolge zu konvertieren/zu analysieren, wenn die Kultur nicht nicht US ist. Die seltsame Sache ist, dass die Zeichenkette erzeugt wurde, indem man das gleiche Format und die gleiche Kultur anwendete wie jene, die verwendet wurden, um es wieder in eine Zeichenkette zu zerlegen. Im folgenden Code werden alle diese Versionen fehlschlagen:String.FormatException mit DateTime in nicht US-Kultur

 
const string culture = "ja-JP"; 
const string format = "dd MMM yyyy"; //error in orignal post included {0:} 
CultureInfo info = new CultureInfo(culture); 
Thread.CurrentThread.CurrentCulture = info; 
Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(culture); 

//string toParse = String.Format(info, format, DateTime.Now); //error in original post 
string toParse = DateTime.Now.ToString(format); 
System.Diagnostics.Debug.WriteLine(string.Format("Culture format = {0}, Date = {1}", culture, toParse)); 
try 
{ 
    DateTime output = DateTime.ParseExact(toParse, format, CultureInfo.InvariantCulture); 
    //DateTime output = DateTime.ParseExact(toParse, format, info); 
    //DateTime output = DateTime.ParseExact(toParse, format, info, DateTimeStyles.None); 
    //DateTime output = Convert.ToDateTime(toParse, info); 
} 
catch (Exception ex) 
{ 
    System.Diagnostics.Debug.WriteLine(ex.Message); 
} 

Beachten Sie, dass die Zeichenfolge für en-US ist „25. Februar 2010“. Die Zeichenfolge für ja-JP ist "25 2 2010".

Irgendeine Idee, wie man "25 2 2010" zurück in ein Datum bekommt?

Vielen Dank im Voraus.

Edit1: Ich sollte beachten, dass die japanische Kultur hier nur als Beispiel fest codiert ist. Ich brauche das wirklich, um mit der Kultur zu arbeiten, die vom Benutzer eingestellt wird. Was ich brauche, ist eine Lösung, bei der das Format für die Datumszeit unabhängig von der Kultur des Benutzers funktioniert. Ich denke, das Single M macht es.

Edit 2: M funktioniert nicht für Englisch. Wer kennt eine Format-Zeichenfolge, die für alle Kulturen funktioniert?

Antwort

3

Wenn Sie ändern:

DateTime output = DateTime.ParseExact(
    toParse, format, CultureInfo.InvariantCulture); 

zu

DateTime output = DateTime.ParseExact(toParse, "dd MMM yyyy", info); 

das Datum korrekt analysiert wird.

Beachten Sie, dass Sie in Ihrem Beispiel eine Kultur (ja-JP) verwenden, um in eine Zeichenfolge zu konvertieren, aber eine andere Kultur, die aus einer Zeichenfolge konvertiert werden soll. Ein weiteres Problem besteht darin, dass String.Format eine Zeichenfolge mit einem zusammengesetzten Format akzeptiert ("My string to format - {0:dd MMM yyyy}"), aber DateTime.ParseExact nur das Format der Datumszeit erwartet.

+0

Wenn Sie 'DateTime.ParseExact' mit' CultureInfo.InvariantCulture' verwenden möchten, dann haben Sie Recht. Wenn Sie die JP-Kultur jedoch verwenden, wird es nicht benötigt. –

+0

Ja, gute Sache mit der Sache {0:} - das war nicht das ultimative Problem, aber es war ein Fehler in meinem Testskript (jetzt behoben). Ich habe auch versucht, die Ja-JP-Kultur während des Parsens zu verwenden - es gibt eine Reihe von Versuchen darin. Nur ging nach Invariant, als das nicht funktionierte. – sydneyos

0

Verwenden Sie ein einzelnes M, wenn Sie das Datum analysieren. Das ist, was in dem Beispiel für die MonthDayPattern für japanische Kultur verwendet wird.

const string format = "{0:dd M yyyy}"; 
+0

Das ist wirklich nicht das Problem. Das OP versucht, die Zeichenfolge des zusammengesetzten Formats als Format für 'DateTime.ParseExact' zu verwenden, das nur das Format der Datumszeit erwartet. –

0
string text = "25 2 2009"; 
DateTime date = DateTime.ParseExact(text, "d M yyyy", CultureInfo.InvariantCulture); 
0

Das Format Muster, das Sie DateTime.ParseExact passieren muss nur das Datum Muster sein, ohne den Platzhalter. Und für JP Kultur, müssen Sie nur eine M verwenden, da die Daten durch Zahlen dargestellt werden, auch wenn MMM angegeben ist, wenn Sie in eine Zeichenfolge konvertieren.

 const string culture = "ja-JP"; 
     const string FROM_STRING_FORMAT = "dd M yyyy"; 
     const string TO_STRING_FORMAT = "{0:" + FROM_STRING_FORMAT + "}"; 
     CultureInfo info = new CultureInfo(culture); 
     Thread.CurrentThread.CurrentCulture = info; 
     Thread.CurrentThread.CurrentUICulture = CultureInfo.CreateSpecificCulture(culture); 

     string toParse = String.Format(info, TO_STRING_FORMAT, DateTime.Now); 
     Console.WriteLine(string.Format("Culture format = {0}, Date = {1}", culture, toParse)); 
     try 
     { 
      DateTime output = DateTime.ParseExact(toParse, FROM_STRING_FORMAT, CultureInfo.InvariantCulture); 
      Console.WriteLine(output); 
     } 
     catch (Exception ex) 
     { 
      Console.WriteLine(ex.Message); 
     } 
+0

Das sieht nach der Antwort aus - funktioniert das für alle Kulturen? – sydneyos

+0

Nein, das funktioniert nicht für ** Englisch **. Japanisch ist ein bisschen ungewöhnlich, wo man selbst bei der Angabe von 'MMM' ein Ergebnis erhält, das nur' M' ist. Daher ist das String-Format 'MMM' nicht round-trip-kompatibel, wenn' ParseExact' mit Japanisch verwendet wird. Die beste Empfehlung, die ich Ihnen geben kann, ist die 'ParseExact' Überladung, die mehrere Formate akzeptiert, wie zum Beispiel:' DateTime.ParseExact (toParse, neu [] {"d M yyyy", "d MMM yyyy"}, CultureInfo.InvariantCulture, DateTimeStyles.None); ' –

+0

João Angelo hat Recht in seinem Beitrag. Das eigentliche Problem mit Ihrem Original besteht darin, dass Sie mit einer bestimmten Kultur in eine Zeichenfolge formatieren und dann versuchen, es mithilfe der invarianten Kultur zu analysieren. Die Formatzeichenfolgen stimmen nicht überein. Wenn Sie die gleichen Kulturinformationen in beiden Formaten verwenden und analysieren, funktioniert es. –