Was ist der Unterschied zwischen withLocale() und localizedBy() in Java DateTimeFormatter?Java

Java-Forum
Anonymous
 Was ist der Unterschied zwischen withLocale() und localizedBy() in Java DateTimeFormatter?

Post by Anonymous »

Code: Select all

DateTimeFormatter
Java 8 führte eine moderne Datums- und Uhrzeit-API mit neuen Typen wie LocalDate ein, die im Paket java.time.* verfügbar sind. Außerdem wurde eine neue DateTimeFormatter-Klasse zum Formatieren (Generieren von Zeichenfolgen aus) dieser Datums- und Uhrzeitangaben bereitgestellt.
Um eine Instanz eines DateTimeFormatter zu erstellen, sollte man seine statischen Methoden/Felder verwenden oder die zugrunde liegende DateTimeFormatterBuilder-Klasse wie in den folgenden Beispielen verwenden:

Code: Select all

DateTimeFormatter.ofPattern("yyyy-MM-dd")
// or
DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL)
// or
DateTimeFormatter.ISO_LOCAL_DATE_TIME
// or
new DateTimeFormatterBuilder().appendValue(ChronoField.YEAR).toFormatter()
Sie alle geben eine unveränderliche DateTimeFormatter-Instanz zurück.
Lokalisierung
Jetzt ist es möglich, einige Aspekte des Formatierers zu überschreiben/zu ändern, indem die Builder-ähnlichen .with***()-Methoden oder ähnliches auf der DateTimeFormatter-Instanz aufgerufen werden, die eine neue Kopieinstanz mit diesem geänderten Aspekt erstellen:

Code: Select all

DateTimeFormatter
.ofPattern("yyyy-MM-dd")
.withChronology(JapaneseChronology.INSTANCE)        // New instance with this chronology
.withDecimalStyle(DecimalStyle.of(Locale.of("fa"))) // New instance with this decimal style
Aber die Lokalisierung (zumindest das Zahlensystem) ist in diesen Fällen nicht korrekt:
  • Wenn kein Gebietsschema für den Formatierer angegeben wird (d. h. implizit das System-/Java-Gebietsschema verwendet wird)
  • Wenn das Standard-Java-Gebietsschema mithilfe von Locale.setDefault(myLocale) festgelegt wird; und dann eine Formatiererinstanz erstellt und verwendet wird
  • Wann Verwendung des Gebietsschemas in der ofPattern("...", myLocale)-Methode von DateTimeFormatter
  • Bei Verwendung des Gebietsschemas in der toFormatter(myLocale)-Methode von DateTimeFormatterBuilder
  • Auch wenn explizit Unicode-Erweiterungen in der Gebietsschemanotation verwendet werden (wie Locale.forLanguageTag("en-u-nu-arabext")) und Verwenden des resultierenden Gebietsschemas in withLocale(myLocale)
Was das unten erläuterte Java-Legacy-DateFormat, ICU4J und JavaScript betrifft, sollten alle oben genannten Fälle entsprechend dem Gebietsschema korrekte Ziffern erzeugen. Aber Java DateTimeFormatter erfordert einen zusätzlichen redundanten Aufruf von localizedBy(myLocale) oder withDecimalStyle(DecimalStyle.of(myLocale)). Viele/die meisten Leute und sogar fortgeschrittene Programmierer verwenden das Gebietsschema in der Methode ofPattern() oder in withLocale() anstelle von localizedBy() und keines davon lokalisiert Dinge wie den Dezimalstil (Ziffern/Zahlen) korrekt. Meiner Meinung nach ist dies definitiv ein Fehler und keine Funktion:
  • Jedes DateTimeFormatter#withLocale sollte durch DateTimeFormatter#localizedBy #910 ersetzt werden
  • Wie formatiere ich ein Datum anhand eines beliebigen Gebietsschemas, das aus einem Sprach-Tag mit Java-Zeit erhalten wurde?
  • (korrigiert) Wie formatiere ich ein LocalDate-Objekt in MM/tt/jjjj und das Format bleibt erhalten
  • (korrigiert) SimpleDateFormat und gebietsschemabasierte Formatzeichenfolge
  • etc.
Im Gegensatz zu withLocale() wird „localizedBy()“ nicht einmal im Javadoc der obersten Ebene der DateTimeFormatter-Klasse erwähnt oder beispielsweise javadoc der ofPattern-Methode.
Die alten Java-Klassen DateFormat und SimpleDateFormat lokalisieren Ziffern ordnungsgemäß:

Code: Select all

var myLocale = Locale.forLanguageTag("fa");
var formatter = new SimpleDateFormat("yyyy-MM-dd", myLocale);
var myDate = formatter.parse("2025-06-28");
formatter.format(myDate); // ۲۰۲۵-۰۶-۲۸
ICU4J formatiert Zahlen sowohl für ältere als auch für moderne Java-Typen korrekt:

Code: Select all

var myLocale = Locale.forLanguageTag("fa");
var formatter = com.ibm.icu.text.SimpleDateFormat("yyyy-MM-dd", myLocale);
var myDate = LocalDate.of(2025, 6, 28);
formatter.format(myDate); // ۱۴۰۴-۰۴-۰۷
Als weiteres Beispiel lokalisiert JavaScript auch alles richtig (einschließlich Ziffern), wenn es die Datumsangaben mit seinen Methoden toLocaleString() oder toLocaleDateString() formatiert:

Code: Select all

let myDate = new Date(2025, 5, 28);
myDate.toLocaleDateString("fa"); // ۱۴۰۴/۴/۷
Frage
  • Was genau sind die Unterschiede zwischen withLocale() und localizedBy()?
  • Wenn localizedBy() ein gründlicher lokalisiertes Ergebnis erzeugt, gibt es einen sinnvollen Anwendungsfall für den Aufruf stattdessen von withLocale()?
Verwandt
  • Wie kann ich Zahlen mit DateTimeFormatter lokalisieren?
  • Wozu dient Locale in DateTimeFormatter?
  • Unicode ICU und nicht java.time.DateTimeFormatter sollte für internationale Datums- und Uhrzeitangaben verwendet werden
  • Ostarabische Ziffern
  • Locale Service Provider (localespi) entfernen

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post