Как правильно парсить дату из 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 шт):
Есть такая библиотека Apache Commons Lang. В ней есть класс DateUtils, в котором есть метод который вам нужен - parseDate.
Ему можно передать список поддерживаемых форматов дат и метод по очереди пробует распарсить даты используя эти форматы. Первый, который формат, который подходит будет использован.
Библиотек таких не видел, но можно попробовать выделить основные моменты и использовать регулярные выражения. Конечно подойдет не под все случай, но большую часть вариантов покроет.
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")));
}
}