问题
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?
回答1:
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.
回答2:
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
来源:https://stackoverflow.com/questions/23739718/getting-nominative-month-name-in-jodatime