abhig abhig - 8 months ago 62
Java Question

Proper Russian month string translation Java

I want to convert a Date in to Russian and using the code below


where locale is of type Locale
The problem is months are not parsed correctly . January is coming as "январь" it should be "января" and February is coming as "февраль" should be "февраля"

and so on...

One idea is to convert incorrect months to proper ones in my logic

Is there any thing by which Java do this automatically ?


Answer Source

On my JDK-6-installation I can reproduce your problem:

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 offers you a solution.

It seems that the JDK has changed the internal default from "standalone-style" (nominative) to "format-style" (genitive).

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

If you need to apply standalone textstyle then you have to set up your own DateTimeFormatterBuilder which requires a little bit more effort, else TextStyle.FULL should be the default.

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)

Workaround for Java-pre-8 using old style:

Define your own text resources (troublesome)!

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

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 does not offer a good solution in a Java-pre-8 environment because it only delegates to JDK. See also a similar issue on Joda-site.

Finally there is also my library Time4J which can solve the problem like Java-8, but uses its own text resources for Russian and understands both forms (old style and standalone-style), so this is a simple solution for older Java-versions (and will of course not be obsoleted by Java-8 due to many other feature enhancements).

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