Frage

Ich habe eine Zeichenfolge, die ein Datum in Französisch locale repräsentiert: 09-Oct-08:

Ich muss Parse , dass String so kam ich mit diesem Simple oben:

String format2 = "dd-MMM-yy";

Aber ich habe ein Problem mit dem Monatsteil, das mit einem Punkt endet voraussichtlich zu sein scheint:

df2.format(new Date());

gibt mir:

 28-oct.-09

Was ist jetzt der beste Weg für mich Simple verstehen ( "09-Oct-08")?

zu machen

Voll Code:

String format2 = "dd-MMM-yy"; 
DateFormat df2 = new SimpleDateFormat(format2,Locale.FRENCH); 
date = df2.parse("09-oct-08"); 

Das gibt mir: java.text.ParseException: unparseable Datum: "09-Oct-08"

Und wenn ich dann versuchen, zu protokollieren:

df2.format(new Date()); 

ich: 28-Oktober-09

War es hilfreich?

Lösung

Dies scheint zu funktionieren:

    DateFormatSymbols dfsFr = new DateFormatSymbols(Locale.FRENCH);
    String[] oldMonths = dfsFr.getShortMonths();
    String[] newMonths = new String[oldMonths.length];
    for (int i = 0, len = oldMonths.length; i < len; ++ i) {
        String oldMonth = oldMonths[i];

        if (oldMonth.endsWith(".")) {
            newMonths[i] = oldMonth.substring(0, oldMonths[i].length() - 1);
        } else {
            newMonths[i] = oldMonth;
        }
    }
    dfsFr.setShortMonths(newMonths);
    DateFormat dfFr = new SimpleDateFormat(
        "dd-MMM-yy", dfsFr);

    // English date parser for creating some test data.
    DateFormat dfEn = new SimpleDateFormat(
        "dd-MMM-yy", Locale.ENGLISH);
    System.out.println(dfFr.format(dfEn.parse("10-Oct-09")));
    System.out.println(dfFr.format(dfEn.parse("10-May-09")));
    System.out.println(dfFr.format(dfEn.parse("10-Feb-09")));

Edit: Sieht aus wie St. Schatten mir, um es zu schlagen

.

Andere Tipps

Sie können einfach entfernen Sie die "":

df2.format(new Date()).replaceAll("\\.", ""));

Bearbeiten, in Bezug auf die Zitrone Antwort:

Es scheint ein Problem mit der Formatierung zu sein, wenn die Locale Französisch verwenden. Daher schlage ich vor, dass Sie einfach die . Entfernung benutzen, wie ich erklärt.

Ja, der folgende Code:

    String format2 = "dd-MMM-yy";
    Date date = Calendar.getInstance().getTime();
    SimpleDateFormat sdf = new SimpleDateFormat(format2, Locale.FRENCH);
    System.out.println(sdf.format(date));
    sdf = new SimpleDateFormat(format2, Locale.ENGLISH);
    System.out.println(sdf.format(date));

zeigt die folgende Ausgabe:

28-oct.-09
28-Oct-09

Bearbeiten wieder

Ok, ich habe das Problem jetzt.

Ich weiß nicht wirklich, wie Sie dieses Problem zunächst ohne Bearbeitung Ihr String lösen können. Die Idee ist der Monat, in dem ursprünglichen String durch einen umfassenden Monat ersetzt werden:

        String[] givenMonths = { "jan", "fév", "mars", "avr.", "mai", "juin", "juil", "août", "sept", "oct", "nov", "déc" };
        String[] realMonths = { "janv.", "févr.", "mars", "avr.", "mai", "juin", "juil.", "août", "sept.", "oct.", "nov.", "déc." };
        String original = "09-oct-08";
        for (int i = 0; i < givenMonths.length; i++) {
            original = original.replaceAll(givenMonths[i], realMonths[i]);
        }
        String format2 = "dd-MMM-yy";
        DateFormat df2 = new SimpleDateFormat(format2, Locale.FRENCH);
        Date date = df2.parse(original);
        System.out.println("--> " + date);

Ich bin damit einverstanden, das ist schrecklich, aber ich sehe keine andere Lösung, wenn Sie SimpleDateFormat und Date Klassen verwenden.

Ein andere Lösung ist es, ein real Datum und Uhrzeit-Bibliothek zu verwenden, statt der ursprünglichen JDK diejenigen, wie Joda Zeit .

String format2 = "dd-MMM-yy";
Date date = Calendar.getInstance().getTime();
SimpleDateFormat sdf = new SimpleDateFormat(format2);
System.out.println(sdf.format(date));

Ausgänge 28-Oct-09

Ich sehe keine Punkte Sir. Haben Sie versucht, neu zu überprüfen Ihre Abzüge? Vielleicht platziert Sie versehentlich eine . neben Ihrem MMM?


Sie bekommen java.text.ParseException: Unparseable date: "09-oct-08" seit "09-oct-08" nicht die Formatierung von Locale.FRENCH überein entweder das Standardgebietsschema verwenden (US glaube ich) oder ein . neben Ihrem oct hinzufügen

Ok, dann versuchen «Brute-Force»:)

DateFormatSymbols dfs = new DateFormatSymbols(Locale.FRENCH);
String[] months = new String[13]
<fill with correct month names or just replace these month, that are not fully correct>
dfs.setMonths(months);
SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yy", dfs);
Date nweDate = sdf.parse("09-fév-08");

java.time

Lassen Sie uns sehen, ob die java.time Rahmen helfen können.

Über java.time

Die java.time Rahmen eingebaut in Java 8 und später verdrängt die lästigen alten java.util.Date/.Calendar Klassen. Die neuen Klassen werden durch den sehr erfolgreichen Joda-Time Rahmen, als seinen Nachfolger bestimmt inspiriert, ähnlich in Konzept, aber neu gestaltet. Definiert durch JSR 310 . Erweitert durch die ThreeTen-Extra Projekt. Sehen Sie sich die Tutorial .

LocalDate

Im Gegensatz zu den alten Klassen, java.time bietet die LocalDate Klasse ein Datum-only-Wert darzustellen, ohne Zeit-of-Tag noch Zeitzone.

Französisch Abkürzungen

Werfen Sie einen Blick auf das, was die Formatierer in java.time für abgekürzte Monatsnamen in de Français erwarten .

Wir können Schleife die Month Enum eine Liste der Monate zu bekommen. In dieser Enum bietet die getDisplayName Verfahren zum Herstellen eines lokalisierten Namen des Monats, zu erzeugen. Dieser Code zeigt, dass das Verfahren die gleiche Ausgabe wie der java.time Formatierer erzeugt.

DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "dd-MMM-yyyy" ).withLocale ( Locale.FRENCH );
for ( Month month : Month.values () ) {
    LocalDate localDate = LocalDate.of ( 2015 , month.getValue () , 1 );
    String output = formatter.format ( localDate );
    String displayName = month.getDisplayName ( TextStyle.SHORT , Locale.FRENCH );
    System.out.println ( "output: " + output + " | displayName: " + displayName );// System.out.println ( "input: " + input + " → " + localDate + " → " + output );
}
output: 01-janv.-2015 | displayName: janv.
output: 01-févr.-2015 | displayName: févr.
output: 01-mars-2015 | displayName: mars
output: 01-avr.-2015 | displayName: avr.
output: 01-mai-2015 | displayName: mai
output: 01-juin-2015 | displayName: juin
output: 01-juil.-2015 | displayName: juil.
output: 01-août-2015 | displayName: août
output: 01-sept.-2015 | displayName: sept.
output: 01-oct.-2015 | displayName: oct.
output: 01-nov.-2015 | displayName: nov.
output: 01-déc.-2015 | displayName: déc.

Wir finden eine Mischung aus 3 und 4 Brief Schreibweisen. Längere Namen werden auf vier Zeichen abgekürzt und eine Periode ( FULL STOP- ). Vier Monate haben Namen kurz genug, um ohne Abkürzung verwendet werden. mars, mai, juin, août

So, wie in den anderen Antworten diskutiert, keine einfache Lösung.

Befestigen Sie die Datenquelle

Mein erster Vorschlag ist, die Datenquelle zu beheben. Diese Quelle versagt scheinbar richtige Französisch Regeln für die Abkürzung zu folgen. Yale stimmt mit Java 8 Verständnis von Französisch. By the way, wenn Ihre Datenquelle zur Festsetzung stark schlage ich vor vierstelligen Jahren als zwei führen zu keinem Ende der Verwirrung und Mehrdeutigkeit verwenden.

Befestigen Sie die Eingabe

Natürlich kann die Quelle aus Ihrer Kontrolle / Einfluss sein. In diesem Fall wie bei den anderen Antworten, müssen Sie möglicherweise ein Brute-Force tun ersetzen vielmehr, dass jede Klugheit versuchen. Auf der anderen Seite, wenn das einzige Problem mit Ihrer Eingabe ist einfach die Zeit (FULL STOP) fehlt, dann könnte man Soft-Code, um die Month Enum anstatt hart Code die falschen Werte verwenden.

Ich würde einen anfänglichen Parse-Versuch machen. Falle für das DateTimeParseException , bevor Sie versuchen, ein Update. Wenn die Ausnahme ausgelöst wird, dann die Eingabe beheben.

Um die Eingabe zu beheben, versuchen Sie, jeden Monat des Jahres durch den möglichen Satz von ENUM-Instanzen Looping. Für jeden Monat, erhalten ihren abgekürzten Namen. Ziehe den Zeitraum (FULL STOP) von dieser Abkürzung, zu entsprechen, was wir vermuten, dass unsere unangebrachter eingehende Wert ist. Testen Sie, ob das in der Tat ein Spiel für die Eingabe ist. Wenn nicht, gehen Sie zum nächsten Monat.

Wenn wir ein Spiel zu tun bekommen, fixieren die Eingabe richtig für die Lokalisierungs-Regeln (Französisch Regeln in unserem Fall) abgekürzt werden. Dann analysiert, um die feste Eingabe. Dies würde unser zweiter Parse-Versuch, wie wir eine erste Versuch nach oben Spitze. Wenn dieser zweite Versuch fehlschlägt, ist etwas sehr falsch, da keineted im FIXME: hier gesehen. Aber normalerweise dieser zweite Parse-Versuch erfolgreich sein wird, und wir können aus der for Schleife des Month Enum bürgen.

Schließlich könnten Sie Erfolg durch Tests überprüfen, ob das Ergebnis immer noch die falsche Flagwert anfänglich ( LocalDate.MIN ).

String input = "09-oct-08"; // Last two digits are Year.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern ( "dd-MMM-yy" ).withLocale ( Locale.FRENCH );
LocalDate localDate = LocalDate.MIN; // Some folks prefer a bogus default value as a success/failure flag rather than using a NULL.
try {
    localDate = LocalDate.parse ( input , formatter );
} catch ( DateTimeParseException e ) {
    // Look for any month name abbreviation improperly missing the period (FULL STOP).
    for ( Month month : Month.values () ) {
        String abbreviation = month.getDisplayName ( TextStyle.SHORT , Locale.FRENCH );
        String abbreviationWithoutFullStop = abbreviation.replace ( "." , "" ); // Get short abbreviation, but drop any period (FULL STOP).
        String proper = "-" + abbreviation + "-";
        String improper = "-" + abbreviationWithoutFullStop + "-";
        if ( input.contains ( improper ) ) {
            String inputFixed = input.replace ( improper , proper );
            try {
                localDate = LocalDate.parse ( inputFixed , formatter );
            } catch ( DateTimeParseException e2 ) {
                // FIXME: Handle this error. We expected this second parse attempt to succeed.
            }
            break; // Bail-out of the loop as we got a hit, matching input with a particular improper value.
        }
    }
}
Boolean success =  ! ( localDate.equals ( LocalDate.MIN ) );
String formatted = formatter.format ( localDate );;
String outputImproper = formatted.replace ( "." , "" );  // Drop any period (FULL STOP).

Dump zu trösten.

System.out.println ( "success: " + success + ". input: " + input + " → localDate: " + localDate + " → formatted: " + formatted + " → outputImproper: " + outputImproper );
  

Erfolg: true. Eingabe: 09-Oct-08 → LOCALDATE: 2008-10-09 → formatiert: 09-Oktober-08 → outputImproper: 09-Oct-08

Ich habe das gleiche Problem (französisch und die zusätzlichen Punkte) und ich glaube, den richtigen Weg, um dieses Problem zu lösen, ist durch global die französisch locale überschrieben werden wie folgt:

import moment from 'moment';
moment.locale('fr', { monthsShort: 'janv_févr_mars_avr_mai_juin_juil_août_sept_oct_nov_déc'.split('_') });

Das ursprüngliche monthsShort französisch-Objekt hat die Punkte wie janv._févr._mars_avr._..., so sind zu entfernen wir sie nur.

Hier ist ein Link docs, wo können Sie überprüfen, welche überschrieben werden können .

Beachten Sie, dass wir nicht brauchen ein komplettes locale Objekt zu übergeben, wenn wir also .: monthsShort nur überschrieben werden sollen.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top