Правильный русский месяц перевода строк Java

Я хочу конвертировать дату в русский язык и использовать код ниже

SimpleDateFormat.getDateInstance(SimpleDateFormat.LONG,locale).format(date);

где локаль имеет тип Locale Проблема в том, что месяцы не анализируются правильно. Январь наступает как "январь" должен быть "январь", а февраль наступает как "февраль" должен быть "февраль"

и так далее...

Одна идея состоит в том, чтобы преобразовать неправильные месяцы в правильные в моей логике

Есть ли какая-нибудь вещь, с помощью которой Java делает это автоматически?

Спасибо

6 ответов

Решение

На моей установке JDK-6 я могу воспроизвести вашу проблему:

Date jud = new SimpleDateFormat("yyyy-MM-dd").parse("2014-02-28");
String month =
    DateFormat.getDateInstance(SimpleDateFormat.LONG, new Locale("ru")).format(jud);
System.out.println(month); // output: 28 Февраль 2014 г.

Java-8 предлагает вам решение.

Кажется, что JDK изменил внутреннее значение по умолчанию с "автономного стиля" (именительного падежа) на "форматного стиля" (родительного падежа).

String date =
  DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL)
  .withLocale(new Locale("ru"))
  .format(LocalDate.of(2014, 2, 28));
System.out.println(date); // output: 28 февраля 2014 г.

Если вам нужно применить автономный текстовый стиль, вы должны настроить свой собственный DateTimeFormatterBuilder что требует немного больше усилий, иначе TextStyle.FULL должно быть по умолчанию.

String m = Month.FEBRUARY.getDisplayName(TextStyle.FULL , new Locale("ru")); 
// февраля (first and last char are different)

String s = Month.FEBRUARY.getDisplayName(TextStyle.FULL_STANDALONE , new Locale("ru")); 
// Февраль (this style can be used in DateTimeFormatterBuilder for the month field, too)

Обходной путь для Java-pre-8 с использованием старого стиля:

Определите свои собственные текстовые ресурсы (хлопотно)!

Locale russian = new Locale("ru");
String[] newMonths = {
  "января", "февраля", "марта", "апреля", "мая", "июня", 
  "июля", "августа", "сентября", "октября", "ноября", "декабря"};
DateFormatSymbols dfs = DateFormatSymbols.getInstance(russian);
dfs.setMonths(newMonths);
DateFormat df = DateFormat.getDateInstance(DateFormat.LONG, russian);
SimpleDateFormat sdf = (SimpleDateFormat) df;
sdf.setDateFormatSymbols(dfs);

Date jud = new SimpleDateFormat("yyyy-MM-dd").parse("2014-02-28");
String month = sdf.format(jud);
System.out.println(month); // output: 28 февраля 2014 г.

Joda-Time не предлагает хорошего решения в среде Java-pre-8, потому что он делегирует только JDK. Смотрите также похожую проблему на сайте Joda.

Наконец, есть также моя библиотека Time4J, которая может решить эту проблему, как Java-8, но использует свои собственные текстовые ресурсы для русского языка и понимает обе формы (старый стиль и автономный стиль), так что это простое решение для старых версий Java (и, конечно, не будет устаревшим в Java-8 из-за многих других улучшений).

System.out.println(
    ChronoFormatter.ofDateStyle(DisplayMode.FULL, new Locale("ru")).format(
        PlainDate.of(2014, Month.FEBRUARY, 28)
    )
); // output: 28 февраля 2014 г.

Для Java 8 вы можете использовать новый шаблон.

Короче говоря: "LLLL" шаблон получит именительный падеж:

new SimpleDateFormat("LLLL", Locale.getDefault()).format(date); // январь

"MMMM" шаблон вернет String в родительном падеже:

new SimpleDateFormat("MMMM", Locale.getDefault()).format(date); // января

В качестве альтернативы, вместо жесткого кодирования русских месяцев в массиве (поскольку у нас есть польский, украинский и другие языки), вы можете использовать java.time.Month ENUM. Содержит оба месяца int число и String название.

Хотя принятые ответы @Meno Hochschild и /questions/24749298/kak-otformatirovat-ispanskij-mesyats-v-predlozhenii-ispolzuya-simpledateformat/24749304#24749304 верны, я хочу добавить немного.

Достаточно установить Locale("ru")затем создайте и примените sdf.format(date),

public static String formatDate(long date, String format) {
    Locale locale = new Locale("ru");
    SimpleDateFormat sdf = new SimpleDateFormat(format, locale);
    return sdf.format(date);
}

Но если вы хотите настроить его, я покажу процесс.

После многих исключений я понял, что рабочие дни начинаются не с понедельника (см. http://jexp.ru/index.php/Java_Tutorial/Data_Type/Date_Format)!

public static String formatDate(long date, String format) {
    //Locale locale = new Locale("fr");
    Locale locale = new Locale("ru");
    DateFormatSymbols dfs = DateFormatSymbols.getInstance(locale);
    String[] months = {
            "января", "февраля", "марта", "апреля", "мая", "июня",
            "июля", "августа", "сентября", "октября", "ноября", "декабря"};
    String[] shortMonths = {
            "янв", "фев", "мар", "апр", "май", "июн",
            "июл", "авг", "сен", "окт", "ноя", "дек"};
    dfs.setMonths(months);
    dfs.setShortMonths(shortMonths);
    String[] weekdays = {"", "Воскресенье", "Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота"};
    String[] shortWeekdays = {"", "вс", "пн", "вт", "ср", "чт", "пт", "сб"};
    dfs.setWeekdays(weekdays);
    dfs.setShortWeekdays(shortWeekdays);

    SimpleDateFormat sdf = new SimpleDateFormat(format, locale);
    sdf.setDateFormatSymbols(dfs);
    return sdf.format(date); // пт, 09 декабря 2016
}

В моей задаче я должен получить только месяц из целого числа, поэтому этот код отлично работает для меня:

      int month=5;//for example
Month.of(month).getDisplayName(TextStyle.FULL_STANDALONE, new Locale("ru"));

AFAIK, в JDK нет поддержки локализации в винительном падеже. Я бы предложил использовать MEDIUM формат даты, чтобы обойти это, если это подходит:15 Фев 1999

В противном случае вам может потребоваться указать собственную локализацию для названий месяцев.

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

У меня была большая головная боль при работе с локалями DateTime и т. Д., Я начал просто переводить "Будни и месяцы" в строковое представление оригинального DateTime.

String originalDate = "Tue, 22 Nov 2016 01:03:00 +0300";
Log.d("Date in Russian",convertStringDateToRussian(linkText));

public String convertStringDateToRussian(String mDate) {

    String[] engWeek = {
            "Mon", "Tue", "Wed", "Thu", "Fri", "Sat",
            "Sun"};
    String[] ruWeek = {
            "Понедельник", "Вторник", "Среда", "Четверг", "Пятница", "Суббота",
            "Воскресенье"};
    String[] engMonths = {
            "Jan", "Feb", "Mar", "Apr", "May", "Jun",
            "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"};
    String[] ruMonths = {
            "января", "февраля", "марта", "апреля", "мая", "июня",
            "июля", "августа", "сентября", "октября", "ноября", "декабря"};
    for (
            int t = 0;
            t < engWeek.length; t++)

    {
        if (mDate.contains(engWeek[t])) {
            mDate = mDate.replace(engWeek[t], ruWeek[t]);
            break;
        }
    }

    for (
            int t = 0;
            t < engMonths.length; t++)

    {
        if (mDate.contains(engMonths[t])) {
            mDate = mDate.replace(engMonths[t], ruMonths[t]);
            break;
        }
    }

    return mDate;
}
Другие вопросы по тегам