String.FormatException с DateTime в неамериканской культуре - PullRequest
8 голосов
/ 26 февраля 2010

Я получаю String.FormatException, пытаясь преобразовать / проанализировать строку, когда культура отличается от неамериканской. Странно то, что строка была сгенерирована с применением того же формата и культуры, что и те, которые использовались для анализа ее обратно в строку. В приведенном ниже коде все эти версии не будут работать:

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

Обратите внимание, что строка для en-US - "25 февраля 2010". Строка для ja-JP - "25 2 2010".

Есть идеи, как вернуть "25 2 2010" в дату?

Заранее спасибо.

Edit1: я должен отметить, что японская культура здесь жестко закодирована только в качестве примера. Мне действительно нужно это для работы с любой культурой, установленной пользователем. Что мне нужно, так это решение, в котором формат даты и времени работает независимо от культуры пользователя. Я думаю, что сингл М делает это.

Редактировать 2: M не работает для английского языка. Кто-нибудь знает строку формата, которая работает для всех культур?

Ответы [ 4 ]

3 голосов
/ 26 февраля 2010

Если вы измените:

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

до

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

дата правильно проанализирована.

Обратите внимание, что в вашем примере вы используете культуру (ja-JP) для преобразования в строку, но другую культуру для преобразования из строки. Другая проблема заключается в том, что String.Format принимает строку составного формата ("My string to format - {0:dd MMM yyyy}"), но DateTime.ParseExact ожидает только формат даты и времени.

0 голосов
/ 26 февраля 2010

Шаблон формата, который вы передаете DateTime.ParseExact, должен быть просто шаблоном даты без заполнителя. А для культуры JP вам нужно использовать только один M, поскольку даты представлены числами, даже если при преобразовании в строку указано MMM.

        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 голосов
/ 26 февраля 2010
string text = "25 2 2009";
DateTime date = DateTime.ParseExact(text, "d M yyyy", CultureInfo.InvariantCulture);
0 голосов
/ 26 февраля 2010

Попробуйте использовать один M при разборе даты. Вот что используется в примере для MonthDayPattern для японской культуры.

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