Правильный русский месяц перевода строк 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;
}