2017-02-15 4 views
4

Mit ru Gebietsschema zurück vollen Monat Name (Февраль), aber mit en nur Nummer (2). DateTimeFormatter funktioniert nicht mit LLLL Muster in en locale

DateTimeFormatter formatter = DateTimeFormatter.ofPattern("LLLL", new Locale("ru")); 
LocalDate.now().format(formatter); 

MMMM Arbeit mit en, aber nicht mit ru (müssen Nominativ) arbeiten.

Wie erhalten Sie den vollständigen Monatsnamen für alle Gebietsschemas?

+0

überprüfen Sie auch diesen Beitrag: http://stackoverflow.com/questions/30518954/datetimeformatter-month-pattern-letter-l-fails – 0x44656e6e795279616e

Antwort

2

Leider druckt the related bug issue JDK-8114833 wurde für Java-8 noch nicht gelöst. Und es ist mir noch nicht klar, ob Java-9 eine Lösung bietet (und da ist das Feature-Freeze-Date schon vorbei). So können Sie entweder folgende Abhilfe anwenden, basierend auf Wissen, welche Sprachen benötigen eine spezielle Standalone-Form (Nominativs) für Monate und welche nicht:

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 
} 

Ich kann nicht sagen, dass ich diese Lösung gefällt, weil es zusätzliche Kenntnisse erfordert, welche Sprachen brauche welches Muster. Aber es ist tatsächlich die einzige Möglichkeit, Ihr Problem im Rahmen von JSR-310 (alias java.time -API) zu lösen.

Durch Testen wir jetzt sehen, dass auch die alte Klasse SimpleDateFormat (Version in Java-8) arbeitet:

Locale locale = new Locale("en"); 

    SimpleDateFormat sdf = new SimpleDateFormat("LLLL", locale); 
    System.out.println(sdf.format(new Date())); 

Aber das Problem zu umgehen hat den starken Nachteil nicht mit einem einfachen Kalendertag mit java.util.Date sondern arbeitet nur .

Oder Sie sind möglicherweise bereit, eine zusätzliche Abhängigkeit zu einer Bibliothek hinzuzufügen, die eine bessere Unterstützung für den Musterbuchstaben "L" UND bessere API-Stil und bessere Leistungsmerkmale hat. Zum Beispiel könnten Sie meine Bibliothek Time4J verwenden. Hier ist eine Demonstration von letzteren Fall, die auch zeigt, wie der unabhängige Format Motor Time4J kann für die JSR-310-Typen (auch in Parsing) verwendet werden:

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 

Für die beste Leistung, empfehle ich den Formatierer lazily speichern in einem ConcurrentHashMap pro Gebietsschema.

0

Für Nominativ haben Sie das Muster zu MM oder LL gesetzt statt MMMM/LLLL

System.out.println(LocalDate.now().format(DateTimeFormatter.ofPattern("MM", new Locale("ru")))); 
System.out.println(LocalDate.now().format(DateTimeFormatter.ofPattern("MM", new Locale("en")))); 

, dass 02 für beide Gegenden

+1

Ich denke, das OP will vollen Monat Namen, keine Zahlen. –

Verwandte Themen