it-swarm.com.de

Wie bekomme ich eine lokalisierte Datumsmusterzeichenfolge?

Es ist ziemlich einfach, Java Date (oder Calendar) -Klassen mithilfe der Instanz von DateFormat zu formatieren und zu analysieren, d. H.

DateFormat formatter = DateFormat.getDateInstance(DateFormat.SHORT, Locale.getDefault());
String today = formatter.format(new Date());

Mein Problem ist: Ich muss diese lokalisierte Musterzeichenfolge erhalten (d. H. Etwas wie "MM/dd/yy"). Dies sollte eine triviale Aufgabe sein, aber ich konnte den Anbieter einfach nicht finden ...

41
Paweł Dyda

Für SimpleDateFormat rufen Sie toLocalizedPattern () auf

EDIT:

Für Java 8 Benutzer:

Die Java 8 Date Time API ähnelt Joda-time. Um ein lokalisiertes Muster zu erhalten, können wir die Klasse DateTimeFormatter verwenden

DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM);

Beachten Sie, dass Sie beim Aufrufen von toString () unter LocalDate das Datum im Format ISO-8601 erhalten

Beachten Sie, dass die Date Time API in Java 8 von Joda Time inspiriert ist und die meisten Lösungen auf zeitbezogenen Fragen basieren können.

Für diejenigen, die noch Java 7 oder älter verwenden:

Sie können so etwas verwenden:

DateFormat formatter = DateFormat.getDateInstance(DateFormat.SHORT, Locale.getDefault());
String pattern       = ((SimpleDateFormat)formatter).toPattern();
String localPattern  = ((SimpleDateFormat)formatter).toLocalizedPattern();

Da die DateFormat-Instanz, die von getDateInstance() zurückgegeben wird, eine Instanz von SimpleDateFormat..__ ist. Diese beiden Methoden sollten auch im DateFormat enthalten sein, damit dies weniger abgehackt wird, dies ist jedoch derzeit nicht der Fall.

29
Zarremgregarrok

Es mag seltsam sein, dass ich meine eigene Frage beantworte, aber ich glaube, ich kann dem Bild etwas hinzufügen.

ICU-Implementierung

Natürlich bietet Java 8 eine Menge, aber es gibt noch etwas anderes: ICU4J . Dies ist eigentlich die Quelle der ursprünglichen Java-Implementierung von Dingen wie Calendar, DateFormat und SimpleDateFormat, um nur einige zu nennen.
Daher sollte es nicht überraschen, dass ICU SimpleDateFormat auch Methoden wie toPattern() oder toLocalizedPattern() enthält. Sie können sie hier in Aktion sehen:

DateFormat fmt = DateFormat.getPatternInstance(
        DateFormat.YEAR_MONTH,
        Locale.forLanguageTag("pl-PL"));

if (fmt instanceof SimpleDateFormat) {
    SimpleDateFormat sfmt = (SimpleDateFormat) fmt;
    String pattern = sfmt.toPattern();
    String localizedPattern = sfmt.toLocalizedPattern();
    System.out.println(pattern);
    System.out.println(localizedPattern);
}

ICU-Verbesserungen

Das ist nichts Neues, aber ich wollte wirklich darauf hinweisen:

DateFormat.getPatternInstance(String pattern, Locale locale);

Dies ist eine Methode, mit der eine Reihe von ländereinstellungsspezifischen Mustern zurückgegeben werden können, z.

  • ABBR_QUARTER
  • QUARTAL
  • JAHR
  • YEAR_ABBR_QUARTER
  • YEAR_QUARTER
  • YEAR_ABBR_MONTH
  • JAHR MONAT
  • YEAR_NUM_MONTH
  • YEAR_ABBR_MONTH_DAY
  • YEAR_NUM_MONTH_DAY
  • JAHR MONAT TAG
  • YEAR_ABBR_MONTH_WEEKDAY_DAY
  • YEAR_MONTH_WEEKDAY_DAY
  • YEAR_NUM_MONTH_WEEKDAY_DAY
  • ABBR_MONTH
  • MONAT
  • NUM_MONTH
  • ABBR_STANDALONE_MONTH
  • STANDALONE_MONTH
  • ABBR_MONTH_DAY
  • MONAT TAG
  • NUM_MONTH_DAY
  • ABBR_MONTH_WEEKDAY_DAY
  • MONTH_WEEKDAY_DAY
  • NUM_MONTH_WEEKDAY_DAY
  • TAG
  • ABBR_WEEKDAY
  • WOCHENTAG
  • STUNDE
  • HOUR24
  • HOUR_MINUTE
  • HOUR_MINUTE_SECOND
  • HOUR24_MINUTE
  • HOUR24_MINUTE_SECOND
  • HOUR_TZ
  • HOUR_GENERIC_TZ
  • HOUR_MINUTE_TZ
  • HOUR_MINUTE_GENERIC_TZ
  • MINUTE
  • MINUTE_SECOND
  • ZWEITE
  • ABBR_UTC_TZ
  • ABBR_SPECIFIC_TZ
  • SPECIFIC_TZ
  • ABBR_GENERIC_TZ
  • GENERIC_TZ
  • LOCATION_TZ

Sicher gibt es einige. Das Gute an ihnen ist, dass diese Muster tatsächlich Strings sind (wie in Java.lang.String). Das heißt, wenn Sie das englische Muster "MM/d" verwenden, erhalten Sie im Gegenzug ein länderspezifisches Muster. In einigen Eckfällen kann es nützlich sein. Normalerweise würden Sie nur die Variable DateFormat verwenden und sich nicht um das Muster selbst kümmern.

Gebietsschema-spezifisches Muster vs. lokalisiertes Muster

Die Frage der Absicht war es, lokalisiert zu werden und nicht das länderspezifische Muster. Was ist der Unterschied?

Theoretisch gibt toPattern() ein ländereinstellungsspezifisches Muster (abhängig von Locale, mit dem Sie (Simple)DateFormat instanziiert haben). Das heißt, egal welche Zielsprache/welches Land Sie verwenden, Sie erhalten das Muster, bestehend aus Symbolen wie y, M, d, h, H, M usw.

Auf der anderen Seite gibt toLocalizedPattern()sollte ein lokalisiertes Muster zurück, das für Endbenutzer zum Lesen und Verstehen geeignet ist. Zum Beispiel wäre das deutsche Datumsmuster (Standarddatum):

  • toPattern (): dd.MM.yyyy
  • toLocalizedPattern (): tt.MM.jjjj (Tag = Tag, Monat = Monat, Jahr = Jahr)

Die Intention der Frage war: "wie man das lokalisierte Muster findet, das als Hinweis auf das Datums-/Zeitformat dienen kann". Das heißt, wir haben ein Datumsfeld, das der Benutzer mit dem ländereinstellungsspezifischen Muster ausfüllen kann, aber ich möchte einen Formathinweis in der lokalisierten Form anzeigen.

Leider gibt es bisher keine gute Lösung. Das ICU, das ich zuvor in diesem Beitrag erwähnt habe, funktioniert teilweise. Die Daten, die ICU verwendet, stammen aus CLDR , was leider teilweise übersetzt/teilweise korrekt ist. Bei der Muttersprache meiner Mutter werden zum Zeitpunkt des Schreibens weder Muster noch ihre lokalisierten Formen korrekt übersetzt. Und jedes Mal, wenn ich sie korrigiere, wurde ich von anderen Leuten überstimmt, die nicht unbedingt in Polen leben oder polnisch sprechen ... 

Die Moral dieser Geschichte: Verlassen Sie sich nicht vollständig auf CLDR. Sie müssen noch lokale Auditoren/Sprachprüfer haben.

19
Paweł Dyda

Sie können DateTimeFormatterBuilder in Java 8 verwenden. Das folgende Beispiel gibt ein lokalisiertes Datumsmuster zurück, z. "d.M.yyyy".

String datePattern = DateTimeFormatterBuilder.getLocalizedDateTimePattern(
  FormatStyle.SHORT, null, IsoChronology.INSTANCE, 
  Locale.GERMANY); // or whatever Locale
11
mikaves

Mit dem folgenden Code erhalten Sie das Muster für das Gebietsschema:

final String pattern1 = ((SimpleDateFormat) DateFormat.getDateInstance(DateFormat.SHORT, locale)).toPattern();
System.out.println(pattern1);
5
Andreas Kozma

Java 8 bietet einige nützliche Funktionen zum Arbeiten und Formatieren/Analysieren von Datum und Uhrzeit, einschließlich der Verarbeitung von Gebietsschemas. Hier ist eine kurze Einführung.

Grundmuster

Im einfachsten Fall zum Formatieren/Analysieren eines Datums würden Sie den folgenden Code mit einem String-Muster verwenden:

DateTimeFormatter.ofPattern("MM/dd/yyyy")

Der Standard ist dann, dies mit dem Date-Objekt direkt zur Formatierung zu verwenden:

return LocalDate.now().format(DateTimeFormatter.ofPattern("MM/dd/yyyy"));

Und dann mit dem Factory-Muster ein Datum analysieren:

return LocalDate.parse(dateString, DateTimeFormatter.ofPattern("MM/dd/yyyy"));

Das Muster selbst hat eine große Anzahl von Optionen, die die Mehrheit der Anwendungsfälle abdecken werden. Einen vollständigen Überblick finden Sie am javadoc-Speicherort hier .

Locales

Das Einfügen eines Gebietsschemas ist ziemlich einfach. Für das Standardgebietsschema haben Sie die folgenden Optionen, die dann auf die oben gezeigten Formatierungs-/Analyseoptionen angewendet werden können:

DateTimeFormatter.ofLocalizedDate(dateStyle);

Bei dem oben angegebenen 'dateStyle' handelt es sich um eine FormatStyle -Option Enum, die die vollständige, lange, mittlere und kurze Version des lokalisierten Datums darstellt, wenn mit DateTimeFormatter gearbeitet wird. Mit FormatStyle haben Sie auch folgende Möglichkeiten:

DateTimeFormatter.ofLocalizedTime(timeStyle);
DateTimeFormatter.ofLocalizedDateTime(dateTimeStyle);
DateTimeFormatter.ofLocalizedDateTime(dateTimeStyle, timeStyle);

Mit der letzten Option können Sie für Datum und Uhrzeit einen anderen FormatStyle angeben. Wenn Sie nicht mit dem Standardgebietsschema arbeiten, können Sie die Rückgabe jeder lokalisierten Methode mithilfe der Option .withLocale anpassen, z

DateTimeFormatter.ofLocalizedTime(timeStyle).withLocale(Locale.ENGLISH);

Alternativ enthält das ofPattern eine überladene Version, um auch das Gebietsschema anzugeben

DateTimeFormatter.ofPattern("MM/dd/yyyy",Locale.ENGLISH);

Ich brauche mehr!

DateTimeFormatter erfüllt die meisten Anwendungsfälle, basiert jedoch auf dem DateTimeFormatterBuilder , der dem Benutzer des Builders eine Vielzahl von Optionen bietet. Verwenden Sie DateTimeFormatter, um mit zu beginnen. Wenn Sie diese umfangreichen Formatierungsfunktionen benötigen, greifen Sie auf den Builder zurück.

4
Jim

In dem folgenden Code finden Sie den Code, der die Gebietsschemainstanz akzeptiert und das für das Gebietsschema spezifische Datenformat/Muster zurückgibt.

 public static String getLocaleDatePattern(Locale locale) {
    // Validating if Locale instance is null
    if (locale == null || locale.getLanguage() == null) {
        return "MM/dd/yyyy";
    }
    // Fetching the locale specific date pattern
    String localeDatePattern = ((SimpleDateFormat) DateFormat.getDateInstance(
            DateFormat.SHORT, locale)).toPattern();
    // Validating if locale type is having language code for Chinese and country 
    // code for (Hong Kong) with Date Format as - yy'?'M'?'d'?'
    if (locale.toString().equalsIgnoreCase("zh_hk")) {
        // Expected application Date Format for Chinese (Hong Kong) locale type
        return "yyyy'MM'dd";
    }
    // Replacing all d|m|y OR Gy with dd|MM|yyyy as per the locale date pattern
    localeDatePattern = localeDatePattern.replaceAll("d{1,2}", "dd").replaceAll(
            "M{1,2}", "MM").replaceAll("y{1,4}|Gy", "yyyy");
    // Replacing all blank spaces in the locale date pattern
    localeDatePattern = localeDatePattern.replace(" ", "");
    // Validating the date pattern length to remove any extract characters
    if (localeDatePattern.length() > 10) {
        // Keeping the standard length as expected by the application
        localeDatePattern = localeDatePattern.substring(0, 10);
    }
    return localeDatePattern;
}
1
Dinesh Lomte

Da es sich nur um das Gebietsschema information handelt, das Sie suchen, denke ich, Sie müssen die Datei suchen, die die JVM (OpenJDK oder Harmony) tatsächlich als Eingabe für die gesamte Locale-Sache verwendet, und herausfinden, wie parse es. Oder nutzen Sie einfach eine andere Quelle im Web (sicherlich gibt es irgendwo eine Liste). Das wird die armen Übersetzer retten.

0
David Bullock