2016-09-23 3 views
0

Я нашел хорошую функцию, которая проверяет формат и правильность даты String. Я хотел обновить его, чтобы проверить только >= 1900 лет.Исключение при проверке строки даты в Java

Так вот что я нашел:

public boolean isDateValid(String date) { 
    try { 
     DateFormat df = new SimpleDateFormat("dd-MM-yyyy"); 
     df.setLenient(false); 
     df.parse(date); 
     return true; 
    } catch (ParseException e) { 
     return false; 
    } 
} 

И это моя обновленная версия:

public boolean isDateValid(String date) { 
    try { 
     DateFormat df = new SimpleDateFormat("dd-MM-yyyy"); 
     df.setLenient(false); 
     df.parse(date); 
     Integer year = Integer.parseInt(date.substring(6, 10)); 
     if (year>= 1900) 
      return true; 
     else 
      return false; 
    } catch (ParseException e) { 
     return false; 
    } 
} 

Таким образом, вместо того, чтобы вернуться правда я проверяю, если переменная year больше или равна 1900 . Проблема заключается в том, что я запускаю эту функцию с помощью "12-12-1xxx" (Редактировать: или "12-12-1abc"). NumberFormatException забрасывается во время разбора года String до int. Это определенно не должно произойти, потому что ParseException следует выбросить первым, сломав блок try {}.

Похоже, что подтверждение от первого листинга не работает должным образом, поскольку оно принимает каждую часть "yyyy", которая начинается с числа. Однако все работает нормально для "12-12-xxxx" (Редактировать: или "12-12-abcd").

EDIT:

Стоп голосование вниз мой вопрос и сосредоточиться в то время как вы читаете. Вопрос очень ясен: почему новый SimpleDateFormat («dd-MM-yyyy»). Parse («12-12-1xxx») не бросает исключение ParseException?

+1

он работает отлично на моей системе, проверьте введенные данные и использовать последнюю версию JDK –

+0

я могу опубликовать снимок (только как ответ), но это не имеет смысла, поэтому проверьте наличие недопустимого ввода –

+0

, да, он тоже работает над моей системой. –

ответ

2

Как я понял из Javadoc SimpleDateFormat займет 1 действительную часть года и будет разбирать его. Вместо этого вы можете попытаться подтвердить дату с помощью регулярных выражений. Вы можете найти некоторые примеры здесь Regex to validate date format dd/mm/yyyy

+0

И, наконец, у нас есть кто-то, кто может читать. Спасибо за решение! –

0

Я проверил вашу функцию и найду данные ниже.

Если вы пройдете12-12-1xxx в основной функции, то и вы получите истинное он не возвращает ложь, даже когда я печатаю вывод даты, который преобразуется по df.parse(date) является 10 октября 00:00:00 GMT 2.

Таким образом, вы не получите исключение синтаксического анализа в любое время для этого,

Предложения

либо изменить ParseException по отклонениям или использовать улов NumberFormatException, как показано ниже.

public boolean isDateValid(String date) { 
    try { 
     DateFormat df = new SimpleDateFormat("dd-MM-yyyy"); 
     df.setLenient(false); 
     df.parse(date); 
     Integer year = Integer.parseInt(date.substring(6, 10)); 
     if (year>= 1900) 
      return true; 
     else 
      return false; 
    } catch (Exception e) { // Use Exception or if you want ParseException then use below commented code 
     return false; 
    } 
    /*catch (NumberFormatException nfe) { // Use this if you use ParseException 
     return false; 
    }*/ 
} 
+1

Это не объясняет, почему ParseException не генерируется при вводе недопустимого ввода. Более того: «Исключение» - это плохая практика, поскольку она включает в себя любые RuntimeExceptions. –

+0

проверьте этот https://docs.oracle.com/javase/7/docs/api/java/text/SimpleDateFormat.html, вы получите представление о том, почему вы не получаете ошибку, поскольку он будет рассматривать этот тип текста в дате согласно по их критериям – Vickyexpert

+0

@LittleSanti это не недопустимый ввод, и поэтому я также показываю вывод этой обработанной даты, так как java doc рассматривает его как проверку даты выше ссылки – Vickyexpert

1

Документация метода parse является:

Анализирует текст с начала данной строки для получения даты. Метод может не использовать весь текст данной строки.

Поскольку вся строка не требуется использовать, тогда «12-12-1xxx» фактически анализируется как «12-12-1», и вы получаете дату года 1.

Вместо использования подстроки вы можете использовать результат метода анализа, чтобы получить год. getYear обесценивается и возвращает смещение с 1900 года, поэтому сначала вы можете конвертировать в Calendar или LocalDate.

public boolean isDateValid(String date) { 
    try { 
     DateFormat df = new SimpleDateFormat("dd-MM-yyyy"); 
     df.setLenient(false); 
     Date parsed = df.parse(date); 
     int year = parsed.getYear() + 1900; 
     if (year >= 1900) 
      return true; 
     else 
      return false; 
    } catch (ParseException e) { 
     return false; 
    } 
} 
+0

Спасибо за объяснение, почему метод «разбора» не выбрасывает исключение. Я думаю, что я дополнительно поймаю NumberFormatException. В любом случае, спасибо за ваше предложение. –

0

Если кто-то заинтересован в том, как должен выглядеть код, вот это:

public boolean isDateValid(String date, String format) { 
    if (date.length()!=format.length()) 
     return false; 
    try { 
     DateFormat df = new SimpleDateFormat(format); 
     df.setLenient(false); 

     df.parse(date); // exception is not thrown if day and month is 
         // correct AND the first char of year is a digit 

     // so if we have correct day and correct month 
     // and we know the year has 4 chars we can try to parse it 
     Integer year = Integer.parseInt(date.substring(6, 10)); 

     if (year>= 1900 && year<=2015) // here we know that the year is 4 digit integer 
      return true;    // and we can limit it 
     else 
      return false; 

    } catch (ParseException e) { 
     return false; 
    } catch (NumberFormatException e) { 
     return false; 
    } 
} 
Смежные вопросы