Анализ SimpleDateFormat (string str) не генерирует исключение, когда str = 2011/12/12aaaaaaaaaa?

Вот пример:

public MyDate() throws ParseException {
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/d");
    sdf.setLenient(false);
    String t1 = "2011/12/12aaa";
    System.out.println(sdf.parse(t1));
}

2011/12/12aaa не является допустимой строкой даты. Однако функция печатает «Mon Dec 12 00:00:00 PST 2011», и ParseException не генерируется.

Может ли кто-нибудь сказать мне, как позволить SimpleDateFormat рассматривать «2011/12/12aaa» как недопустимую строку даты и выдавать исключение?


person Terminal User    schedule 08.12.2011    source источник


Ответы (7)


В JavaDoc на parse(...) указано следующее:

синтаксический анализ не обязательно использует все символы до конца строки

Похоже, вы не можете заставить SimpleDateFormat генерировать исключение, но вы можете сделать следующее:

SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/d");
sdf.setLenient(false);
ParsePosition p = new ParsePosition( 0 );
String t1 = "2011/12/12aaa";    
System.out.println(sdf.parse(t1,p));

if(p.getIndex() < t1.length()) {
  throw new ParseException( t1, p.getIndex() );
}

По сути, вы проверяете, использовал ли синтаксический анализ всю строку, и если нет, у вас есть неверный ввод.

person Thomas    schedule 08.12.2011

Чтобы проверить, действительна ли дата, следующий метод возвращает значение, если дата действительна, в противном случае он вернет false.

public boolean isValidDate(String date) {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/d");
        Date testDate = null;
        try {
            testDate = sdf.parse(date);
        }
        catch (ParseException e) {
            return false;
        }
        if (!sdf.format(testDate).equals(date)) {
            return false;
        }
        return true;

    }

Посмотрите на следующий класс, который может проверить, действительна ли дата или нет.

** Образец примера**

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

public class DateValidCheck {


    public static void main(String[] args) {

        if(new DateValidCheck().isValidDate("2011/12/12aaa")){
            System.out.println("...date is valid");
        }else{
            System.out.println("...date is invalid...");
        }

    }


    public boolean isValidDate(String date) {

        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/d");
        Date testDate = null;
        try {
            testDate = sdf.parse(date);
        }
        catch (ParseException e) {
            return false;
        }
        if (!sdf.format(testDate).equals(date)) {
            return false;
        }
        return true;

    }

}
person Sunil Kumar Sahoo    schedule 08.12.2011

Java 8 LocalDate может использоваться:

public static boolean isDate(String date) {
try {
        LocalDate.parse(date, DateTimeFormatter.ofPattern("yyyy/MM/dd"));
        return true;
    } catch (DateTimeParseException e) {
        return false;
    }
}

Если входной аргумент "2011/12/12aaaaaaaaa", выход false;

Если входной аргумент "2011/12/12", выход true

person David    schedule 16.05.2017

После успешного анализа всей строки шаблона SimpleDateFormat прекращает оценку данных, которые были переданы для анализа.

person DerMike    schedule 08.12.2011

Взгляните на документацию метода, в которой говорится: ParseException if the beginning of the specified string cannot be parsed.

Исходный код метода с javadoc:

/**
 * 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.
 * <p>
 * See the {@link #parse(String, ParsePosition)} method for more information
 * on date parsing.
 *
 * @param source A <code>String</code> whose beginning should be parsed.
 * @return A <code>Date</code> parsed from the string.
 * @exception ParseException if the beginning of the specified string
 *            cannot be parsed.
 */
public Date parse(String source) throws ParseException
{
    ParsePosition pos = new ParsePosition(0);
    Date result = parse(source, pos);
    if (pos.index == 0)
        throw new ParseException("Unparseable date: \"" + source + "\"" ,
            pos.errorIndex);
    return result;
}
person amra    schedule 08.12.2011

Вы можете использовать класс ParsePosition или функцию sdf.setLenient(false)

Документы: http://docs.oracle.com/javase/7/docs/api/java/text/ParsePosition.html http://docs.oracle.com/javase/7/docs/api/java/text/DateFormat.html#setLenient%28boolean%29

person Michel    schedule 08.12.2011
comment
Я думаю, что метод синтаксического анализа заботится только о начальной позиции, а не о конечной позиции. isLenient не работает - person Terminal User; 08.12.2011
comment
При связывании JavaDocs попробуйте связать текущую версию (7, а не 1.4.2). - person Thomas; 08.12.2011
comment
@TerminalUser мм Я пробовал это сам на примере, но setLiniet(), похоже, не работает, а ParsePosition работает только тогда, когда действительно возникает исключение. Вы можете проверить, имеют ли обе строки одинаковую длину после синтаксического анализа без исключения, а затем создать руководство по исключению. Не совсем то, что вы просите, но... - person Michel; 08.12.2011

Простая установка sdf.setLenient(false) сделает свое дело.

person Manoj Kancherla    schedule 12.04.2019