Unfortunately the related bug issue JDK-8114833 has not yet been solved for Java-8. And it is not yet clear for me if Java-9 offers a solution (and there the feature-freeze-date is already over). So you can either apply following workaround based on your knowledge which languages need a special standalone-form (nominative) for months and which not:
private static final Set<String> LANGUAGES_WITH_STANDALONE_CASE;
static {
Set<String> set = new HashSet<>();
set.add("ru");
// add more languages which require LLLL-pattern (for example other slavish languages)
LANGUAGES_WITH_STANDALONE_CASE = Collections.unmodifiableSet(set);
}
public static void main(String[] args) throws Exception {
Locale locale = new Locale("en");
DateTimeFormatter formatter =
DateTimeFormatter.ofPattern(
LANGUAGES_WITH_STANDALONE_CASE.contains(locale.getLanguage())
? "LLLL" : "MMMM",
locale
);
System.out.println(LocalDate.now().format(formatter));
// ru => Февраль
// en => February
}
I cannot say that I like this solution because it requires extra knowledge which languages need which pattern. But it is actually the only possibility to solve your problem within the scope of JSR-310 (aka java.time
-API).
By testing I see now that even the old class SimpleDateFormat
(version in Java-8) works:
Locale locale = new Locale("en");
SimpleDateFormat sdf = new SimpleDateFormat("LLLL", locale);
System.out.println(sdf.format(new Date()));
But that workaround has the strong disadvantage not to work with a plain calendar date but with java.util.Date
only.
Or you might be willing to add an extra dependency to a library which has better support for the pattern letter "L" AND has better API-style AND better performance characteristics. For example you could use my library Time4J. Here a demonstration of latter case which also shows how the independent format engine of Time4J can be used for the JSR-310-types (also in parsing):
Locale locale = new Locale("ru");
ChronoFormatter<LocalDate> formatter =
ChronoFormatter.ofPattern(
"LLLL",
PatternType.CLDR,
locale,
PlainDate.axis(TemporalType.LOCAL_DATE)
);
System.out.println(formatter.format(LocalDate.now()));
// ru => Февраль
// en => February
For best performance, I recommend to lazily store the formatter in a ConcurrentHashMap
per locale.