2017-07-26 7 views
1

Ich versuche, das Format eines String Datum erhalten EEEE MMMM d-MM/d/yyyy durch, zuerst zu ändern, es in eine LocalDate Umwandlung und dann einen Formatierer von einem anderen Muster auf die LocalDate genommen werden, bevor das Parsen in String wieder.Java: Können nicht LOCALDATE von TemporalAccessor

Hier ist mein Code:

private String convertDate(String stringDate) 
{ 
    //from EEEE MMMM d -> MM/dd/yyyy 

    DateTimeFormatter formatter = new DateTimeFormatterBuilder() 
      .parseCaseInsensitive() 
      .append(DateTimeFormatter.ofPattern("EEEE MMMM d")) 
      .toFormatter(); 

    LocalDate parsedDate = LocalDate.parse(stringDate, formatter); 
    DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("MM/d/yyyy"); 

    String formattedStringDate = parsedDate.format(formatter2); 

    return formattedStringDate; 
} 

Allerdings habe ich diese Ausnahme Nachricht bekommen, dass ich nicht wirklich verstehen:

Exception in thread "main" java.time.format.DateTimeParseException: Text 'TUESDAY JULY 25' could not be parsed: Unable to obtain LocalDate from TemporalAccessor: {DayOfWeek=2, MonthOfYear=7, DayOfMonth=25},ISO of type java.time.format.Parsed 
    at java.time.format.DateTimeFormatter.createError(DateTimeFormatter.java:1920) 
+3

Nun, Sie können kein Datum ohne ein Jahr haben. – RealSkeptic

+2

Sie haben nicht gesagt, was Sie erwarten, das Jahr zu sein. Das laufende Jahr? Immer 2017? Berechnen Sie das Jahr basierend auf der Kombination von Wochentag und Wochentag? Entweder KayV oder Hugo ist abhängig von Ihrem Anwendungsfall am nächsten. – JodaStephen

+0

Near-Duplicate von [Java Autocomplete/Format Datum von MM-DD-Eingabe] (https://StackOverflow.com/questions/43858077/java-autocomplete-format-date-from-mm-dd-input) –

Antwort

2

Wie die anderen Antworten bereits sagte, um eine LocalDate zu erstellen, benötigen Sie die Jahr, die nicht in der Eingabe String ist. Es hat nur Tag, Monat und Tag der Woche.

Um die vollen LocalDate zu erhalten, müssen Sie den Tag und Monat und finden Sie ein Jahr, in dem dieser Tag/Monat Kombination entspricht den Tag der Woche analysieren.

Natürlich könnten Sie den Tag der Woche und davon ausgehen, ignorieren, dass das Datum immer im aktuellen Jahr; In diesem Fall lieferten die anderen Antworten bereits die Lösung.Aber wenn Sie das Jahr finden möchten, das genau dem Wochentag entspricht, müssen Sie Schleife, bis Sie es finden.

Ich bin auch einen Formatierer mit einem java.util.Locale zu schaffen, um es explizit zu machen, dass ich Monat und Tag der Woche Namen auf Englisch will. Wenn Sie kein Gebietsschema angeben, verwendet es den Standardwert des Systems, und es ist nicht garantiert, dass es immer Englisch ist (und es kann ohne Ankündigung auch zur Laufzeit geändert werden).

DateTimeFormatter formatter = new DateTimeFormatterBuilder() 
    .parseCaseInsensitive() 
    .append(DateTimeFormatter.ofPattern("EEEE MMMM d")) 
    // use English Locale to correctly parse month and day of week 
    .toFormatter(Locale.ENGLISH); 
// parse input 
TemporalAccessor parsed = formatter.parse("TUESDAY JULY 25"); 
// get month and day 
MonthDay md = MonthDay.from(parsed); 
// get day of week 
DayOfWeek dow = DayOfWeek.from(parsed); 
LocalDate date; 
// start with some arbitrary year, stop at some arbitrary value 
for(int year = 2017; year > 1970; year--) { 
    // get day and month at the year 
    date = md.atYear(year); 
    // check if the day of week is the same 
    if (date.getDayOfWeek() == dow) { 
     // found: 'date' is the correct LocalDate 
     break; 
    } 
} 

In diesem Beispiel habe ich angefangen im Jahr 2017 und versucht, ein Datum, bis zurück bis 1970 zu finden, aber Sie können auf die Werte anzupassen, die Ihre Fälle Anwendung passt.

Sie können auch das aktuelle Jahr (anstelle von einigen festen willkürlichen Wert) mit Year.now().getValue() erhalten.

1

Die Dokumentation für LocalDate sagt, dass

LocalDate ist ein unveränderliches Datum-Uhrzeit-Objekt, das ein Datum darstellt, das oft als Jahr-Monat-Tag betrachtet wird. Zum Beispiel kann der Wert "2. Oktober 2007" in einem LocalDate gespeichert werden.

In Ihrem Fall der Eingang String ist einen wichtigen Bestandteil der LocalDate, das heißt das Jahr fehlt. Was du im Grunde hast, ist Monat und Tag. Sie können also eine Klasse verwenden, die für diesen MonthDay geeignet ist. Mit, dass Ihr Code kann geändert werden:

DateTimeFormatter formatter = new DateTimeFormatterBuilder() 
       .parseCaseInsensitive() 
       .append(DateTimeFormatter.ofPattern("EEEE MMMM d")) 
       .toFormatter(); 

MonthDay monthDay = MonthDay.parse(stringDate, formatter); 
LocalDate parsedDate = monthDay.atYear(2017); // or whatever year you want it at 
DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("MM/d/yyyy"); 

String formattedStringDate = parsedDate.format(formatter2); 
System.out.println(formattedStringDate); //For "TUESDAY JULY 25" input, it gives the output 07/25/2017 
1

Hier ist die kleine Änderung, die Sie implementieren müssen:

private static String convertDate(String stringDate) 
{ 
    //from EEEE MMMM d -> MM/dd/yyyy 

    DateTimeFormatter formatter = new DateTimeFormatterBuilder().appendPattern("EEEE MMMM dd") 
             .parseDefaulting(ChronoField.YEAR, 2017) 
             .toFormatter(); 

    LocalDate parsedDate = LocalDate.parse(stringDate, formatter); 
    DateTimeFormatter formatter2 = DateTimeFormatter.ofPattern("MM/d/yyyy"); 

    String formattedStringDate = parsedDate.format(formatter2); 

    return formattedStringDate; 
} 
  1. den Standard chronologisches Jahr in den Formatierungs hinzufügen .parseDefaulting(ChronoField.YEAR, 2017)

  2. mit
  3. Rufen Sie die Methode mit dem Argument "Tuesday July 25" wie folgt auf convertDate("Tuesday July 25");

+1

Ich glaube, dass Dies bestätigt, dass der Wochentag des erlangten Datums mit dem Wochentag in der Eingabezeichenfolge übereinstimmt, was wir wohl wollen. Das ist gut. –

0

Eine weitere Option ist die folgende (genau wie die anderen Antworten ein bisschen hacky) zu tun, vorausgesetzt natürlich, Sie das Datum wollen im laufenden Jahr fallen:

LocalDate localDate = LocalDate.parse(stringDate + " " +LocalDate.now().getYear(), DateTimeFormatter.ofPattern("EEEE MMMM d"); 
Verwandte Themen