Проблема с простым форматом даты Java

Я работаю над проектом, в котором мне нужно проверить несколько дат на основе длины и шаблонов. Я использую простой формат даты и нашел много проблем с этим. Мое требование - строго разрешить, если строка даты соответствует "гггг / мм / дд" и строго 10 символов.

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

public static boolean checkformat(String dateString){
        boolean flag = false;
        Date d1 = null;
        SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
        format.setLenient(false);
        try {
            d1 = format.parse(dateString);
            flag=true;
        } catch (ParseException ex) {
            ex.printStackTrace();
            return false;
        }
        return flag;
    }

Приведенный выше код возвращает "true" для различных входов, таких как "99/03/1" (должно быть 0099/03/01) и 99/1/1(должно быть 0099/01/1). Поскольку входные строки не приходят из объекта from, я не могу выполнить проверки перед передачей их этому методу. Пожалуйста, предложите любую реализацию, которая должна действовать очень строго по отношению к формату даты ("гггг / мм / дд").

4 ответа

Я предлагаю вам попытаться проверить дату с помощью регулярного выражения перед форматированием.

код пользователя для подтверждения

public static boolean checkformat(String dateString){
        boolean flag = false;
        Date d1 = null;
        SimpleDateFormat format = new SimpleDateFormat("yyyy/MM/dd");
        format.setLenient(false);
        try {
             if (dateString.matches("([0-9]{4})/([0-9]{2})/([0-9]{2})")) { // use this regex
               d1 = format.parse(dateString);
               flag=true;
             }
        } catch (ParseException ex) {
            ex.printStackTrace();
            return false;
        }
        return flag;
    }
String[] removeSlashes=new String[3];
removeSlashes = enteredDate.split("/");

if(removeSlashes[0].length()!=4)
     throw new IncorrectDateFormatException(); // user defined exception
if(removeSlashes[1].length()!=2)
     throw new IncorrectDateFormatException();
if(removeSlashes[2].length()!=2)
     throw new IncorrectDateFormatException();

//Then use SimpleDateFormat to verify

Вы можете попробовать использовать новый пакет java.time из Java 8 и более поздних версий. Вы можете использовать его как замену SimpleDateFormat:

public static boolean checkformat(String dateString){
    boolean flag = false;

    try {
        TemporalAccessor ta = DateTimeFormatter.ofPattern("yyyyMMdd").parse(strDate);
        flag=true;
    } catch (DateTimeParseException ex) {
        ex.printStackTrace();
        return false;
    }
    return flag;
}

Это также ограничивает значения от бессмысленности (например, значение месяца 18).

Хорошо, во-первых: вы знаете, в каком формате вы ожидаете. Так зачем просто разбирать его и ловить исключение, а не проверять предварительные условия?

if(dateString.size() > 10) {
...

На самом деле вы не проверяете свой входной формат, а скорее анализируете его - хотя метод не выражает этот контракт - поэтому, если ваш метод предназначен только для проверки, вы можете: 1. Использовать регулярное выражение 2. ...? Я знаю, что в сети довольно много ответов, в которых предлагается использовать SimpleDateFormat, но, честно говоря, они ошибочны. Если я ожидаю заданный формат, например, поскольку я знаю, что были сделаны преобразования для некоторого пользовательского ввода, я могу начать анализ строки и, учитывая, что что-то могло пойти не так, поймать исключение. Если я не знаю, какой формат передан мне, я нахожусь на уровне проверки, и этот уровень не должен пытаться выполнить преобразование, а скорее является доказательством того, что преобразование будет действительным.

Другие вопросы по тегам