2010-02-25 16 views
8

Estoy obteniendo una String.FormatException intentando convertir/analizar una cadena cuando la cultura es distinta a la no estadounidense. Lo curioso es que la cadena fue generada al aplicar el mismo formato y cultura que los que se utilizan para analizar de nuevo en una cadena. En el código siguiente, todas estas versiones se producirá un error:String.FormatException con DateTime en cultura no estadounidense

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

Tenga en cuenta que la cadena de es-es "25 feb 2010". La cadena para ja-JP es "25 2 2010".

¿Alguna idea de cómo obtener "25 2 2010" de nuevo en una fecha?

Gracias de antemano.

Edit1: Debo señalar que la cultura japonesa está codificada aquí solo como un ejemplo. Realmente necesito que esto funcione con cualquier cultura que establezca el usuario. Lo que necesito es una solución donde el formato de fecha y hora funcione sin importar la cultura del usuario. Creo que el single M lo hace.

Editar 2: M no funciona para inglés. ¿Alguien sabe una cadena de formato que funciona para todas las culturas?

Respuesta

3

Si cambia:

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

a

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

la fecha se analiza correctamente.

Tenga en cuenta que en su ejemplo está utilizando una cultura (ja-JP) para convertir a cadena pero otra cultura para convertir de cadena. Otro problema es que String.Format acepta una cadena de formato compuesto ("My string to format - {0:dd MMM yyyy}"), pero DateTime.ParseExact solo espera el formato de fecha y hora.

+0

Si desea utilizar 'DateTime.ParseExact' con' CultureInfo.InvariantCulture', entonces sí, tiene razón. Sin embargo, si utiliza el cultivo de JP, no es necesario. –

+0

Sí, buena observación de lo de {0:}: ese no era el último problema, pero era un error en mi script de prueba (ahora corregido). También intenté usar la cultura ja-JP durante el análisis: hay una serie de intentos allí. Solo fui a Invariant cuando eso no funcionaba. – sydneyos

0

Pruebe usar una sola M al analizar la fecha. Eso es lo que se usa en el ejemplo del MonthDayPattern para la cultura japonesa.

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

Eso realmente no es el problema. El OP intenta usar la cadena de formato compuesto como el formato para 'DateTime.ParseExact', que solo espera el formato de fecha y hora. –

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

El formato patrón se pasa a DateTime.ParseExact tiene que ser sólo el patrón de fecha, sin que el marcador de posición. Y para cultura JP, necesita usar solo un M ya que las fechas están representadas por números incluso cuando se especifica MMM al convertir a una cadena.

 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

Parece la respuesta: ¿funciona para todas las culturas? – sydneyos

+0

No, esto no funciona para ** Inglés **. El japonés es un poco inusual, donde incluso cuando especificabas 'MMM' obtienes un resultado que es solo' M'. Por lo tanto, el formato de cadena 'MMM' no es compatible con el viaje de ida y vuelta cuando se usa' ParseExact' con japonés. La mejor recomendación que puedo darte es utilizar la sobrecarga 'ParseExact' que acepta múltiples formatos, como este:' DateTime.ParseExact (toParse, new [] {"d M yyyy", "d MMM yyyy"}, CultureInfo.InvariantCulture, DateTimeStyles.None); ' –

+0

João Angelo está en su puesto. El problema real con su original es que está formateando en cadena con una cultura específica, y luego intenta analizarlo utilizando una cultura invariable. Las cadenas de formato no coinciden. Si usa la misma información cultural tanto en formato como en análisis, funciona. –

Cuestiones relacionadas