2014-04-15 6 views
5

Ich verwende den hier enthaltenen Code, um festzustellen, ob die angegebenen Werte gültige Daten sind. Unter einem speziellen Fall ist es die Bewertung der folgenden Adresse:Java DateFormat.parse denkt "100 112TH AVE NE" ist ein Datum

100 112th Ave NE

Offensichtlich kein Datum, aber Java interpretiert sie als:

Sun 12. Januar 00: EST 00:00 100

Der Code in Frage:

String DATE_FORMAT = "yyyyMMdd"; 
try { 
    DateFormat dfyyyyMMdd = new SimpleDateFormat(DATE_FORMAT); 
    dfyyyyMMdd.setLenient(false); 
    Date formattedDate; 
    formattedDate = dfyyyyMMdd.parse(aValue); 
    console.debug(String.format("%s = %s","formattedDate",formattedDate)); 
} catch (ParseException e) { 
    // Not a date 
} 

Die Konsole kehrt:

11: 41: 40,063 DEBUG TestValues ​​| formatedDate = So Jan 12 00:00:00 EST 100

Irgendeine Idee, was hier vor sich geht?

+3

Also, warum übergeben Sie eine Adresse an das Datum Formatter? –

+2

(Sieht für mich aus wie es Jahr analysiert = 100, Monat = 1, Tag = 12, das ist das Beste, was man hoffen könnte.) –

+0

das ist lustig :-) [sorry] – Leo

Antwort

6

Die Methode parse überprüft nicht, dass die gesamte Zeichenfolge beim Parsen verbraucht wurde. Sie können nach einem gültigen Datum einen zufälligen Müll haben und alles funktioniert. In diesem Fall ist es ein wenig überraschend, dass 100 112 erfolgreich als Datum geparst werden kann, aber es kann.

Sie können ParsePosition angeben, um sicherzustellen, dass die gesamte Zeichenfolge beim Parsen verbraucht wurde.

ParsePosition pos = new ParsePosition(0); 
dfyyyyMMdd.parse(aValue, pos); 
if (pos.getIndex() != aValue.length()) { 
    // there's garbage at the end 
} 
+2

Natürlich sollte man sichergehen, dass der "Überschuss" nicht einfach Whitespace ist. –

+0

Ich musste auch überprüfen, dass jede Zeichenfolge nicht leer war. Wenn 'pos == 0' und der String leer ist,' pos.getIndex == aValue.length() == 0'. – bobanahalf

+0

@Joni, ich habe damit einen Test gemacht, und ParsePosition scheint viel effizienter zu sein. Der Test analysierte 3 Millionen Werte, einige gültige Daten, einige Fehler. Ergebnisse in Nanosekunden: 'joda.parseDateTime == 16,480,274,565; dateTime.parse == 18,584,338,145; dateTime.parse + pos == 2,292,225,286'. Ich konnte in Joda kein Äquivalent zu ParsePosition finden. – bobanahalf

3

Gemäß der documentation kann die Parse-Methode NICHT den gesamten Text des Strings verwenden -

public Date parse(String source) 
       throws ParseException 

    Parses text from the beginning of the given string to produce a date. 
    The method may not use the entire text of the given string. 

überprüfte ich die source code für Simple und stellte fest, dass es die Zeichenfolge nur bis parst auf die Länge der compiledPattern.

So sind die Saiten der Form -

yyyyMMdd(followed by anything) 

wird ohne Fehler analysiert werden.

So z.B. es analysiert auch -

"10000514blabla" --> Tue May 14 00:00:00 EST 1000 
"100 112"  --> Sun Jan 12 00:00:00 EST 100 
"1 112xyz"  --> Wed Jan 12 00:00:00 EST 1