Вопрос

У меня есть строка, которая представляет дату в французском языке: 09-окт-08:

Мне нужно разобрать эту строку, чтобы я придумал этот SimpleDateFormat:

String format2 = "dd-MMM-yy";

Но у меня есть проблема с частью месяца, которая, как представляется, ожидается с конечной точкой:

df2.format(new Date());

дает мне:

 28-oct.-09

Что для меня сейчас лучший способ понять SimpleDateFormat (" 09-oct-08 ")?

Полный код:

String format2 = "dd-MMM-yy"; 
DateFormat df2 = new SimpleDateFormat(format2,Locale.FRENCH); 
date = df2.parse("09-oct-08"); 

Это дает мне: java.text.ParseException: Неразборчивая дата: " 09-oct-08 "

И если я тогда попытаюсь войти:

df2.format(new Date()); 

Я получаю: 28 октября 2009 года.

Это было полезно?

Решение

Кажется, это работает:

    DateFormatSymbols dfsFr = new DateFormatSymbols(Locale.FRENCH);
    String[] oldMonths = dfsFr.getShortMonths();
    String[] newMonths = new String[oldMonths.length];
    for (int i = 0, len = oldMonths.length; i < len; ++ i) {
        String oldMonth = oldMonths[i];

        if (oldMonth.endsWith(".")) {
            newMonths[i] = oldMonth.substring(0, oldMonths[i].length() - 1);
        } else {
            newMonths[i] = oldMonth;
        }
    }
    dfsFr.setShortMonths(newMonths);
    DateFormat dfFr = new SimpleDateFormat(
        "dd-MMM-yy", dfsFr);

    // English date parser for creating some test data.
    DateFormat dfEn = new SimpleDateFormat(
        "dd-MMM-yy", Locale.ENGLISH);
    System.out.println(dfFr.format(dfEn.parse("10-Oct-09")));
    System.out.println(dfFr.format(dfEn.parse("10-May-09")));
    System.out.println(dfFr.format(dfEn.parse("10-Feb-09")));

Редактировать: похоже, что Св. Тень победил меня.

Другие советы

Вы можете просто удалить ". ":

df2.format(new Date()).replaceAll("\\.", ""));
<Ч>

Отредактируйте ответ lemon :

Кажется, проблема с форматированием при использовании французского языка. Таким образом, я предлагаю вам просто использовать удаление . , как я объяснил.

Действительно, следующий код:

    String format2 = "dd-MMM-yy";
    Date date = Calendar.getInstance().getTime();
    SimpleDateFormat sdf = new SimpleDateFormat(format2, Locale.FRENCH);
    System.out.println(sdf.format(date));
    sdf = new SimpleDateFormat(format2, Locale.ENGLISH);
    System.out.println(sdf.format(date));

отображает следующий вывод:

28-oct.-09
28-Oct-09
<Ч>

Изменить еще раз

Хорошо, я понял твою проблему прямо сейчас.

Я действительно не знаю, как вы можете решить эту проблему без предварительной обработки вашей строки. Идея состоит в том, чтобы заменить месяц в исходной строке на полный месяц:

        String[] givenMonths = { "jan", "fév", "mars", "avr.", "mai", "juin", "juil", "août", "sept", "oct", "nov", "déc" };
        String[] realMonths = { "janv.", "févr.", "mars", "avr.", "mai", "juin", "juil.", "août", "sept.", "oct.", "nov.", "déc." };
        String original = "09-oct-08";
        for (int i = 0; i < givenMonths.length; i++) {
            original = original.replaceAll(givenMonths[i], realMonths[i]);
        }
        String format2 = "dd-MMM-yy";
        DateFormat df2 = new SimpleDateFormat(format2, Locale.FRENCH);
        Date date = df2.parse(original);
        System.out.println("--> " + date);

Я согласен, это ужасно, но я не вижу другого решения, если вы используете классы SimpleDateFormat и Date .

Другое решение заключается в использовании реальной библиотеки даты и времени вместо оригинальной библиотеки JDK, такой как Joda Time .

String format2 = "dd-MMM-yy";
Date date = Calendar.getInstance().getTime();
SimpleDateFormat sdf = new SimpleDateFormat(format2);
System.out.println(sdf.format(date));

Выходы 28-окт-09

Я не вижу никаких точек, сэр. Вы пробовали перепроверить ваши отпечатки? Может быть, вы случайно поместили . рядом с MMM ?

<Ч>

Вы получаете java.text.ParseException: дата не разборчива: " 09-oct-08 " , так как " 09-oct-08 " не совпадает форматирование Locale.FRENCH либо использует локаль по умолчанию (думаю, США), либо добавляет . рядом с oct

Хорошо, тогда попробуйте & # 171; грубую силу & # 187; :)

DateFormatSymbols dfs = new DateFormatSymbols(Locale.FRENCH);
String[] months = new String[13]
<fill with correct month names or just replace these month, that are not fully correct>
dfs.setMonths(months);
SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yy", dfs);
Date nweDate = sdf.parse("09-fév-08");

java.time

Давайте посмотрим, поможет ли каркас java.time .

О java.time

java.time фреймворк, встроенный в Java 8 и более поздние версии, заменяет проблемные старые классы java.util.Date/.Calendar. Новые классы вдохновлены очень успешной Joda-Time платформой, задуманной как ее преемник. в концепции, но перестроен. Определено JSR 310 . Расширена проектом ThreeTen-Extra . См. учебник .

<код> LocalDate

В отличие от старых классов, java.time предлагает LocalDate класс для представления значения только для даты, без времени суток и часового пояса.

Французские сокращения

Посмотрите, что ожидают средства форматирования в java.time для сокращенных названий месяцев в en Fran & # 231; ais .

Мы можем зациклить Месяц перечисление, чтобы получить список месяцев. Это перечисление предлагает getDisplayName метод генерации локализованного названия месяца. Этот код демонстрирует, что метод производит тот же вывод, что и форматтер java.time.

DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "dd-MMM-yyyy" ).withLocale ( Locale.FRENCH );
for ( Month month : Month.values () ) {
    LocalDate localDate = LocalDate.of ( 2015 , month.getValue () , 1 );
    String output = formatter.format ( localDate );
    String displayName = month.getDisplayName ( TextStyle.SHORT , Locale.FRENCH );
    System.out.println ( "output: " + output + " | displayName: " + displayName );// System.out.println ( "input: " + input + " → " + localDate + " → " + output );
}
output: 01-janv.-2015 | displayName: janv.
output: 01-févr.-2015 | displayName: févr.
output: 01-mars-2015 | displayName: mars
output: 01-avr.-2015 | displayName: avr.
output: 01-mai-2015 | displayName: mai
output: 01-juin-2015 | displayName: juin
output: 01-juil.-2015 | displayName: juil.
output: 01-août-2015 | displayName: août
output: 01-sept.-2015 | displayName: sept.
output: 01-oct.-2015 | displayName: oct.
output: 01-nov.-2015 | displayName: nov.
output: 01-déc.-2015 | displayName: déc.

Мы находим смесь из трех и четырех букв. Длинные имена сокращаются до четырех символов плюс точка ( FULL STOP ). Четыре месяца имеют достаточно короткие имена, чтобы их можно было использовать без сокращений: mars , mai , juin , ao & # 251; t .

Итак, как уже говорилось в других ответах, простого решения нет.

Исправьте источник данных

Мое первое предложение - исправить ваш источник данных. Этот источник, по-видимому, не соответствует надлежащим французским правилам аббревиатуры. Yale согласен с пониманием французского языка в Java 8. Кстати, если вы исправляете ваш источник данных, я настоятельно рекомендую использовать четырехзначные годы, так как два приводят к бесконечной путанице и неопределенности.

Исправить ввод

Конечно, источник может быть вне вашего контроля / влияния. В этом случае, как и в случае с другими Ответами, вам может потребоваться сделать грубую замену, а не пытаться применить какой-либо ум. С другой стороны, если единственная проблема с вашим вводом - просто пропустить точку (FULL STOP), то вы можете использовать программный код, используя перечисление Month , а не жестко кодировать неправильные значения.

Я бы сделал начальную попытку разбора. Ловушка для DateTimeParseException , прежде чем пытаться исправить. Если выброшено исключение, исправьте ввод.

Чтобы исправить ввод, попробуйте каждый месяц года, зацикливая возможный набор экземпляров enum. За каждый месяц получайте его сокращенное название. Удалите точку (FULL STOP) из этой аббревиатуры, чтобы она соответствовала тому, что мы подозреваем, является нашим неправильным входящим значением. Проверьте, действительно ли это соответствует входным данным. Если нет, переходите к следующему месяцу.

Когда мы получим совпадение, исправьте правильное сокращение ввода для правил локали (в нашем случае это французские правила). Затем проанализируйте фиксированный ввод. Это будет наша вторая попытка разбора, так как мы сделали первоначальную попытку наверху. Если вторая попытка не удалась, что-то

У меня была та же проблема (французская и лишние точки), и я считаю, что правильный способ решить эту проблему - переписать французскую локаль в общем виде следующим образом:

import moment from 'moment';
moment.locale('fr', { monthsShort: 'janv_févr_mars_avr_mai_juin_juil_août_sept_oct_nov_déc'.split('_') });

Оригинальный французский объект monthsShort имеет такие точки, как janv._f & # 233; vr._mars_avr ._... , поэтому мы просто удаляем их.

Вот ссылка на документы , где вы можете проверить, что можно перезаписать .

Обратите внимание, что нам не нужно передавать полный объект локали, если мы просто хотим перезаписать, т.е.: monthsShort .

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top