Правильный перевод строки в русском языке Java
Я хочу преобразовать дату на русский и использовать код ниже
SimpleDateFormat.getDateInstance(SimpleDateFormat.LONG,locale).format(date);
где locale имеет тип Locale
Проблема в том, что месяцы не обрабатываются правильно. Январь идет как "январь", он должен быть "января", а февраль идет как "февраль" должен быть "февраля"
и т.д.
Одна из идей - преобразовать неправильные месяцы в правильные в моей логике
Есть ли какие-либо вещи, с помощью которых Java делает это автоматически?
Спасибо
Ответы
Ответ 1
В моей 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(
PlainDate.formatter(DisplayMode.FULL, new Locale("ru")).format(
PlainDate.of(2014, Month.FEBRUARY, 28)
)
); // output: 28 февраля 2014 г.
Ответ 2
Для Java 8 вы можете использовать новый шаблон.
Вкратце:
Образец "LLLL"
получит номинальный случай:
new SimpleDateFormat("LLLL", Locale.getDefault()).format(date); // январь
Образец "MMMM"
вернет String
в родительном случае:
new SimpleDateFormat("MMMM", Locale.getDefault()).format(date); // января
В качестве альтернативы вместо жесткого кодирования русских месяцев в массиве (поскольку у нас есть языки на польском, украинском и других языках), вы можете использовать перечисление java.time.Month
. Он содержит как месяцы int
, так и String
.
Ответ 3
AFAIK, нет поддержки локализации в винительном падеже в JDK. Я бы предложил использовать формат даты MEDIUM
для работы, если это подходит:
15 Фев 1999
В противном случае вам может потребоваться предоставить ваши собственные локализации для имен месяцев.
Ответ 4
Хотя принятый ответ @Meno Hochschild и fooobar.com/questions/549688/... верны, я хочу добавить немного.
Достаточно установить 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#Change_date_formatting_symbols)!
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
}
Ответ 5
Извините, если мой ответ не будет полностью соответствовать этому вопросу, но все же "Я хотел бы поделиться своим путем решения проблемы с переводом даты в русский формат.
У вас была большая головная боль при работе с DateTime Locales и т.д., я начал просто переводить дни недели и месяцы в строковое представление исходной даты.
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;
}