8

I need to get month name according to it's number in different Locales.

To do this I create a DateTime (or YearMonth, doesn't matter) Object and get its monthOfYear Property:

YearMonth md = new YearMonth(1992, month);
System.out.println(md.monthOfYear().getAsText(new Locale("ru")));

The thing is that works fine for English language, because Nominative and Genitive names are the same, but for other languages it returns only Genitive, which is not what I need.

How to get Nominative month name?

msrd0
  • 7,816
  • 9
  • 47
  • 82
troy
  • 704
  • 8
  • 16

2 Answers2

6

I think you're confusing genitive with nominative. When I run the following code:

import org.joda.time.YearMonth;
import java.util.Locale;

public class X {

    public static void main(String[] s){
        for (int i = 1;i<13; i++) {
            YearMonth md = new YearMonth(1992, i);
            System.out.println(md.monthOfYear().getAsText(new Locale("ru")));
        }
    }
}

I get the following result:

Январь
Февраль
Март
Апрель
Май
Июнь 
Июль
Август
Сентябрь
Октябрь
Ноябрь
Декабрь

Which is, for my Russian knowledge :) nominative. You probably need to get genitive, but I doubt Joda supports it. You're free to implement it yourself, please see this question: Month name in genitive (Polish locale) with Joda-Time DateTimeFormatter

Community
  • 1
  • 1
Marcin Szawurski
  • 1,313
  • 12
  • 15
  • 1
    I copy-pasted and run Your code and I get Genitive result: января февраля марта апреля ... :) What is your version of jodatime? Mine is 2.3 – troy Aug 24 '14 at 17:51
  • Wow, that's interesting... I use 2.4 but cannot reproduce this by switching the Joda version. Maybe it has sth to do with: https://bugs.openjdk.java.net/browse/JDK-8054482 – Marcin Szawurski Aug 24 '14 at 19:58
  • I believe this depends on the Java version. What Java do both of you have? – Marwin Nov 12 '14 at 11:42
  • @marwin it seems that Java7 has nominative form and Java8 genitive. Just checked this right now - my junit fails on Java8. – Mikhail Kuchma May 12 '16 at 07:25
  • Yes, exactly. It relates to the new Time API of Java 8. Will summarize in a separate answer. – Marwin Oct 24 '16 at 11:52
4

There was a significant (backward-incompatible!) change in the way month names are localized in Java 7 and Java 8.

This relates to the new java.time API (Tutorial) introduced by Java 8. The API (quite reasonably) distinguishes two different forms of a month name, as defined by java.time.format.TextStyle enum:

  • Standalone, which represents the month name as it is. It corresponds to the "nominative" in many languages.
  • Standard, which is typically used inside complete date representations. This corresponds to the "genitive".

The default variant for date formatter is "standard", which also seems reasonable, as formatters are typically used to produce complete dates. Unfortunately, this lead to a change in behavior (at least for some languages) between Java 7 (which used to produce standalone names) and Java 8 (which produces a "standard" name).

It is possible to explicitely ask for the standalone/nominative form by using the above-mentioned TextStyle enumeration. Unfortunately, this makes your code dependent on Java 8 or higher.

Quick demo:

import java.time.Month;
import java.time.format.TextStyle;
import java.util.Locale;

for (TextStyle ts : TextStyle.values()) {
    System.out.print(ts + ":  ");
    System.out.print(Month.OCTOBER.getDisplayName(ts, Locale.ENGLISH ) + " / ");  // English
    System.out.print(Month.OCTOBER.getDisplayName(ts, Locale.forLanguageTag("cs")) + " / ");  // Czech
    System.out.print(Month.OCTOBER.getDisplayName(ts, Locale.forLanguageTag("ru")) + " / ");  // Russian
    System.out.println(Month.OCTOBER.getDisplayName(ts, Locale.forLanguageTag("pl")));  // Polish
}

Which prints:

FULL:  October / října / октября / października
FULL_STANDALONE:  10 / říjen / Октябрь / październik
SHORT:  Oct / Říj / окт / paź
SHORT_STANDALONE:  10 / X / Окт. / paź
NARROW:  O / ř / О / p
NARROW_STANDALONE:  10 / ř / О / p

I do not know of any easy way to get the standalone form that would be working under both Java 7 and Java 8. At least not in pure Java - of course, there are some complicated and more fragile ways, like trying to detect Java version or using some third-party library.

Basil Bourque
  • 303,325
  • 100
  • 852
  • 1,154
Marwin
  • 2,655
  • 1
  • 19
  • 17
  • 1
    Much of the java.time functionality is back-ported to Java 6 & 7 in [*ThreeTen-Backport*](http://www.threeten.org/threetenbp/). Further adapted for Android in the [*ThreeTenABP*](https://github.com/JakeWharton/ThreeTenABP) project. – Basil Bourque Oct 24 '16 at 21:33