Как правильно парсить дату из String в Java

Пользователь вводит дату dd.MM.yyyy (20.03.2020), но не всегда пользователь следует правилу и может ввести (05/03/2020) или (5.3.20). Чтоб не писать свою проверку ввода данных пользователя, есть ли уже готовая библиотека, которая решит проблему неправильного ввода данных, чтоб не грузить код лишними костылями?

static SimpleDateFormat dateFormat = new SimpleDateFormat("dd.MM.yyyy");

short days, months, years;
days = (short) Integer.parseInt(date1.substring(0, 2));
months = (short) Integer.parseInt(date1.substring(3, 5));
years = (short) Integer.parseInt(date1.substring(6, 10));
if (days > 0 || days < 31 ||
    months > 0 || months < 12 ||
    years > 1900 || years < 2100) {
        java.sql.Date sqlDate = null;
        try {
            sqlDate = new java.sql.Date(dateFormat.parse(date1).getTime());
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return sqlDate;
    }


Ответы (2 шт):

Автор решения: Roman-Stop RU aggression in UA

Есть такая библиотека Apache Commons Lang. В ней есть класс DateUtils, в котором есть метод который вам нужен - parseDate.

Ему можно передать список поддерживаемых форматов дат и метод по очереди пробует распарсить даты используя эти форматы. Первый, который формат, который подходит будет использован.

→ Ссылка
Автор решения: Alex Krass

Библиотек таких не видел, но можно попробовать выделить основные моменты и использовать регулярные выражения. Конечно подойдет не под все случай, но большую часть вариантов покроет.

public class DateUtils {
    static final int BOUNDARY_VALUE = 25;
    static final Pattern PATTERN = Pattern.compile("(\\d{1,2}).(\\d{1,2}).((\\d{4})|(\\d{2}))");
    static final SimpleDateFormat FORMATTER = new SimpleDateFormat("dd.MM.yyyy");


    public static Date parseDate(String date) {
        Date result = null;
        Matcher matcher = PATTERN.matcher(date);

        if (matcher.find()) {
            String day = String.format("%2s", matcher.group(1));
            String month = String.format("%2s", matcher.group(2));

            String year = matcher.group(3);
            year = year.length() > 2
                    ? year
                    : Integer.parseInt(year) < BOUNDARY_VALUE ? ("20" + year) : ("19" + year);

            try {
                result = FORMATTER.parse(String.format("%s.%s.%s", day, month, year));
            } catch (ParseException e) {
                e.printStackTrace();
            }
        }
        return result;
    }
}

class DateUtilsTest {
    @Test
    public void PositiveTests() {
        Date date = new GregorianCalendar(1975, Calendar.FEBRUARY, 3).getTime();

        assertEquals(0, date.compareTo(DateUtils.parseDate("3.2.75")));
        assertEquals(0, date.compareTo(DateUtils.parseDate("03.2.75")));
        assertEquals(0, date.compareTo(DateUtils.parseDate("3.02.75")));
        assertEquals(0, date.compareTo(DateUtils.parseDate("03.02.75")));
        assertEquals(0, date.compareTo(DateUtils.parseDate("3.2.1975")));
        assertEquals(0, date.compareTo(DateUtils.parseDate("03.02.1975")));
        assertEquals(0, date.compareTo(DateUtils.parseDate("03,02,1975")));
    }
}
→ Ссылка