wake-up-neo.net

SimpleDateFormat und locale-basierte Formatzeichenfolge

Ich versuche, ein Datum in Java auf unterschiedliche Weise basierend auf dem angegebenen Gebietsschema zu formatieren. Zum Beispiel möchte ich, dass englische Benutzer "1. November 2009" (formatiert mit "MMM d, yyyy") und norwegische Benutzer "1. nov. 2009" ("d. MMM. Yyyy") sehen.

Der Monatsteil funktioniert in Ordnung, wenn ich das Gebietsschema zum SimpleDateFormat-Konstruktor hinzufüge, aber wie sieht es mit dem Rest aus?

Ich hatte gehofft, dass ich mit SimpleDateFormat gepaarte Formatstrings mit Gebietsschemas hinzufügen könnte, aber ich finde keine Möglichkeit, dies zu tun. Ist es möglich oder muss mein Code das Gebietsschema überprüfen und die entsprechende Formatzeichenfolge hinzufügen?

69
fiskeben

Verwenden Sie DateFormat.getDateInstance (int style, Locale locale) , anstatt eigene Muster mit SimpleDateFormat zu erstellen.

77
jarnbjo

SimpleDateFormat dateFormat = new SimpleDateFormat("EEEE dd MMM yyyy", Locale.ENGLISH);
String formatted = dateFormat.format(the_date_you_want_here);
72
redochka

Verwenden Sie das Gebietsschema style +: DateFormat.getDateInstance (int style, locale locale) 

Check http://Java.Sun.com/j2se/1.5.0/docs/api/Java/text/DateFormat.html

Führen Sie das folgende Beispiel aus, um die Unterschiede zu sehen:

import Java.text.DateFormat;
import Java.util.Date;
import Java.util.Locale;

public class DateFormatDemoSO {
  public static void main(String args[]) {
    int style = DateFormat.MEDIUM;
    //Also try with style = DateFormat.FULL and DateFormat.SHORT
    Date date = new Date();
    DateFormat df;
    df = DateFormat.getDateInstance(style, Locale.UK);
    System.out.println("United Kingdom: " + df.format(date));
    df = DateFormat.getDateInstance(style, Locale.US);
    System.out.println("USA: " + df.format(date));   
    df = DateFormat.getDateInstance(style, Locale.FRANCE);
    System.out.println("France: " + df.format(date));
    df = DateFormat.getDateInstance(style, Locale.ITALY);
    System.out.println("Italy: " + df.format(date));
    df = DateFormat.getDateInstance(style, Locale.JAPAN);
    System.out.println("Japan: " + df.format(date));
  }
}

Ausgabe:

United Kingdom: 25-Sep-2017
USA: Sep 25, 2017
France: 25 sept. 2017
Italy: 25-set-2017
Japan: 2017/09/25
26
JuanZe

tl; dr

LocalDate.now().format(
    DateTimeFormatter.ofLocalizedDate( FormatStyle.MEDIUM )
                     .withLocale( new Locale( "no" , "NO" ) )
)

Die problematischen Klassen von Java.util.Date Und SimpleDateFormat sind jetzt Legacy, ersetzt durch die Java.time-Klassen.

LocalDate

Die Klasse LocalDate repräsentiert einen Datumswert ohne Uhrzeit und ohne Zeitzone.

Eine Zeitzone ist für die Bestimmung eines Datums von entscheidender Bedeutung. Für jeden Moment variiert das Datum rund um den Globus je nach Zone. Zum Beispiel ist ein paar Minuten nach Mitternacht in Paris Frankreich ein neuer Tag, während noch „gestern“ in Montréal Québec .

ZoneId z = ZoneId.of( "America/Montreal" );
LocalDate today = LocalDate.now( z );

DateTimeFormatter

Verwenden Sie DateTimeFormatter , um Zeichenfolgen zu generieren, die nur den Datums- oder den Zeitabschnitt darstellen.

Die Klasse DateTimeFormatter kann automatisch localize .

Geben Sie zum Lokalisieren Folgendes an:

  • FormatStyle um zu bestimmen, wie lang oder abgekürzt der String sein soll.
  • Locale um (a) die menschliche Sprache für die Übersetzung von Name des Tages, Name des Monats und dergleichen zu bestimmen, und (b) die kulturellen Normen, die Fragen der Abkürzung, Großschreibung, Zeichensetzung entscheiden , und derartige.

Beispiel:

Locale l = Locale.CANADA_FRENCH ; 
DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( FormatStyle.FULL ).withLocale( l );
String output = ld.format( f );

In die andere Richtung können Sie eine lokalisierte Zeichenfolge analysieren.

LocalDate ld = LocalDate.parse( input , f );

Beachten Sie, dass das Gebietsschema und die Zeitzone vollständig orthogonale Probleme sind. Sie können sich einen Montréal-Moment auf Japanisch oder einen Auckland New Zealand-Moment auf Hindi präsentieren lassen.

Ein weiteres Beispiel: Ändern Sie 6 junio 2012 (Spanisch) in 2012-06-06 (Standard ISO 8601 Format). Die Java.time-Klassen verwenden standardmäßig ISO 8601-Formate zum Parsen/Generieren von Zeichenfolgen.

String input = "6 junio 2012";
Locale l = new Locale ( "es" , "ES" );
DateTimeFormatter f = DateTimeFormatter.ofPattern ( "d MMMM uuuu" , l );
LocalDate ld = LocalDate.parse ( input , f );
String output = ld.toString();  // 2012-06-06. 

Formate durchlesen

Hier ist ein Beispielcode zum Durchlesen der Ergebnisse mehrerer Formate in mehreren Gebietsschemas, die automatisch lokalisiert werden.

Ein EnumSet ist eine Implementierung von Set , die sowohl für eine geringe Speichernutzung als auch für eine schnelle Ausführungsgeschwindigkeit beim Sammeln von Enum Objekte. Also gibt EnumSet.allOf( FormatStyle.class ) uns eine Sammlung aller vier zu schleifenden FormatStyle enum-Objekte. Weitere Informationen finden Sie unter Oracle Tutorial zu Aufzählungstypen .

LocalDate ld = LocalDate.of( 2018 , Month.JANUARY , 23 );

List < Locale > locales = new ArrayList <>( 3 );
locales.add( Locale.CANADA_FRENCH );
locales.add( new Locale( "no" , "NO" ) );
locales.add( Locale.US );

// Or use all locales (almost 800 of them, for about 120K text results).
// Locale[] locales = Locale.getAvailableLocales(); // All known locales. Almost 800 of them.

for ( Locale locale : locales )
{
    System.out.println( "------|  LOCALE: " + locale + " — " + locale.getDisplayName() + "  |----------------------------------" + System.lineSeparator() );

    for ( FormatStyle style : EnumSet.allOf( FormatStyle.class ) )
    {
        DateTimeFormatter f = DateTimeFormatter.ofLocalizedDate( style ).withLocale( locale );
        String output = ld.format( f );
        System.out.println( output );
    }
    System.out.println( "" );
}
System.out.println( "« fin »" + System.lineSeparator() );

Ausgabe.

------|  LOCALE: fr_CA — French (Canada)  |----------------------------------

mardi 23 janvier 2018
23 janvier 2018
23 janv. 2018
18-01-23

------|  LOCALE: no_NO — Norwegian (Norway)  |----------------------------------

tirsdag 23. januar 2018
23. januar 2018
23. jan. 2018
23.01.2018

------|  LOCALE: en_US — English (United States)  |----------------------------------

Tuesday, January 23, 2018
January 23, 2018
Jan 23, 2018
1/23/18

« fin »

About Java.time

Das Java.time Framework ist in Java 8 und höher. Diese Klassen ersetzen das lästige alte Legacy Datum-Zeit-Klassen wie Java.util.Date , Calendar , & SimpleDateFormat .

Das Joda-Time -Projekt, das sich jetzt im Wartungsmodus befindet, rät zur Migration in die Java.time -Klassen.

Weitere Informationen finden Sie im Oracle Tutorial . Durchsuchen Sie Stack Overflow nach vielen Beispielen und Erklärungen. Spezifikation ist JSR 31 .

Sie können Java.time Objekte direkt mit Ihrer Datenbank austauschen. Verwenden Sie einen JDBC-Treiber , der JDBC 4.2 oder höher entspricht. Keine Notwendigkeit für Zeichenketten, keine Notwendigkeit für Klassen Java.sql.*.

Woher bekomme ich die Java.time-Klassen?

Das Projekt ThreeTen-Extra erweitert Java.time um zusätzliche Klassen. Dieses Projekt ist ein Testfeld für mögliche zukünftige Ergänzungen von Java.time. Hier finden Sie möglicherweise einige nützliche Klassen wie Interval , YearWeek , YearQuarter und mehr .

13
Basil Bourque

Lokalisierung der Datumszeichenfolge:

Basierend auf dem Beitrag von redsonic:

private String localizeDate(String inputdate, Locale locale) { 

    Date date = new Date();
    SimpleDateFormat dateFormatCN = new SimpleDateFormat("dd-MMM-yyyy", locale);       
    SimpleDateFormat dateFormat = new SimpleDateFormat("dd-MMM-yyyy");


    try {
        date = dateFormat.parse(inputdate);
    } catch (ParseException e) {
        log.warn("Input date was not correct. Can not localize it.");
        return inputdate;
    }
    return dateFormatCN.format(date);
}

String localizedDate = localizeDate("05-Sep-2013", new Locale("zh","CN"));

wird wie 05- 九月 -2013 sein

7
Yaro

Das Datum wird entsprechend dem aktuellen Gebietsschema des Benutzers angezeigt:

import Java.text.DateFormat;    
import Java.util.Date;

Date date = new Date();
DateFormat df = DateFormat.getDateTimeInstance();
String myDate = df.format(date);

31. Dezember 1969 7:00:02 PM 

DateFormat.getDateInstance() 

31. Dezember 1969

1
live-love
String text = new SimpleDateFormat("E, MMM d, yyyy").format(date);
0
Hadid Graphics

Java 8 Style für ein bestimmtes Datum

LocalDate today = LocalDate.of(1982, Month.AUGUST, 31);
System.out.println(today.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(Locale.ENGLISH)));
System.out.println(today.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(Locale.FRENCH)));
System.out.println(today.format(DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM).withLocale(Locale.JAPANESE)));
0
Mircea Stanciu