Есть ли эффективный способ проверить, представляет ли строка дату?

Мне дают txt с определенным форматом. Формат должен начинаться с dd/MM/uuuu. Однако я хотел бы проверить, действительно ли это этот конкретный формат, иначе мой код сломается.

Теперь мои мысли заключались в том, чтобы проверить, могут ли конкретные 10 первых символов (с разделителями) определять объект LocalDate. Итак, я придумал это:

public boolean isDate(String date) {

    DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/uuuu");
    LocalDate ld = null;
    try {
        ld = LocalDate.parse(date, formatter);
        System.out.println(ld);
    } catch (DateTimeParseException e) {
        System.out.println("Date " + date + " is not a date.");
        return false;

    }

    return true;
}

Однако это не лучшая практика, потому что я контролирую поток программы с помощью исключений. Кроме того, мне нужно проверить еще 8 полей, чтобы представить время и т. д., поэтому мой код будет полон попыток. Есть ли более эффективный способ обойти это?


person Kostas Thanasis    schedule 07.11.2019    source источник
comment
Я не думаю, что это плохая практика в этом примере. По крайней мере, я лично никогда не слышал, чтобы блоки try/catch ухудшали ход выполнения программы. Весь этот метод тестирования основан на идее синтаксического анализа строки на другой тип данных и отлова потенциального исключения, что строка не может быть преобразована. Могу я спросить, как вы пришли к выводу, что перехват исключений в подобных ситуациях не является хорошей практикой?   -  person yur    schedule 07.11.2019
comment
Однако это не лучшая практика, потому что я контролирую поток программы с исключениями. Плохая практика? И почему?   -  person Roberto Manfreda    schedule 07.11.2019
comment
Я не думаю, что есть альтернатива, если вы не используете менее ограничительную проверку, такую ​​​​как регулярное выражение.   -  person AndyMan    schedule 07.11.2019
comment
Когда я прочитал только заголовок этого вопроса, прежде чем щелкнуть его, чтобы увидеть сам вопрос, решение, которое появилось в моей голове, было похоже на то, что вы уже сделали.   -  person Roger Gustavsson    schedule 07.11.2019
comment
@RogerGustavsson То же самое, я думал, что еще один бедняга пытался придумать какое-нибудь регулярное выражение, но нет, у него уже есть эффективное решение, и он спрашивает нас, основываясь на все еще неподтвержденном утверждении, что это решение является плохой практикой.   -  person yur    schedule 07.11.2019
comment
Пункт 57: Используйте исключения только в исключительных случаях. Тот факт, что формат неверен или указанная строка не представляет дату, не является чем-то исключительным. Я просто не буду обрабатывать дату из этой конкретной строки. Нет причин создавать исключение для этого. Я, однако, использую исключение вместо многих условий if then. Это мое понимание предмета. Обратите внимание, что я студент бакалавриата без опыта, поэтому я не знаю, если мои мнения верны.   -  person Kostas Thanasis    schedule 07.11.2019
comment
Мнения всегда справедливы, и я не намного опытнее! Пункт 57? Что это за предмет, о котором вы говорите? Я думаю, что вы слишком далеко думаете об этом. Именно так выполняется тестирование типов данных в Java, это наиболее эффективный способ, он читается чисто и не влияет на производительность, чего еще можно желать? Как сказал @Kayaman, если бы существовал собственный метод isDate(String string), код для него выглядел бы так.   -  person yur    schedule 07.11.2019
comment
Я думаю, что пункт 57 может относиться к случаю, когда вы позволяете исключениям всплывать вверх в иерархии вызовов. Делайте это только в исключительных случаях. Совершенно нормально использовать исключения, как это сделано в этом случае.   -  person Roger Gustavsson    schedule 07.11.2019
comment
@Костас Танасис - здесь вы не генерируете исключение, вы ловите то, которое выдается методом синтаксического анализа. Таким образом, вы не нарушаете пункт 57. Если бы вы генерировали новое исключение или повторно генерировали то, которое вы поймали, то вы бы нарушили указанный принцип.   -  person Michael Gantman    schedule 07.11.2019
comment
Да, исключения для потока управления является антишаблоном. Однако я, конечно, считаю это исключением (извините), когда это нормально. Это способ, который предлагает библиотека, и по уважительной причине, поскольку нам часто нужно сообщение о том, почему какой-то формат недействителен, для этого подходит сообщение об исключении. И ваше заявление try короткое и легко читаемое. Я бы тоже так поступил.   -  person Ole V.V.    schedule 07.11.2019


Ответы (2)


В рассматриваемом коде нет ничего плохого. Это ясно и читабельно, и нет очевидных проблем с производительностью (конечно, вы можете кэшировать DateTimeFormatter, если хотите, но это не будет иметь значения). Исключения также не вызывают значительного снижения производительности, поскольку yur упоминается.

Это не случай потока управления исключениями. Единственный способ узнать, является ли это датой, - это проанализировать ее. Парсер выдаст исключение, если это не так. LocalDate.tryParse() нет, но если бы он был, это выглядело бы как код в вопросе.

Это случай «я слышал/я был в предположении», и хотя некоторые вещи были реальной проблемой в прошлом (например, медленная синхронизация), обычно они основаны на устаревших версиях Java, выпущенных более 10 лет назад или проблема понимается неправильно (например, исключения / поток управления).

person Kayaman    schedule 07.11.2019

Однажды у меня была очень интересная задача — проверить, представляет ли какая-либо строка дату в любом формате. Мне пришла в голову интересная идея. в двух словах, он должен хранить список всех форматов даты, которые вы хотите поддерживать в качестве внешнего свойства, а затем проверять свою строку по каждому формату один за другим. Но это еще не все. Например порядок форматов имеет значение. Я написал статью по этому вопросу. Вот ссылка на него: Java 8 Java . Пакет Time: анализ любой строки на дату

person Michael Gantman    schedule 07.11.2019
comment
Формат известен здесь, так зачем мучиться? - person Joakim Danielson; 07.11.2019
comment
Я предложил очень общее решение. Это может быть перебор - person Michael Gantman; 07.11.2019
comment
Если вы находитесь в исключительной ситуации, когда вам нужно поддерживать неизвестное количество различных форматов, вам действительно нужно индивидуальное решение, которое сильно зависит от данных. - person Kayaman; 07.11.2019
comment
@JoakimDanielson Эх, вроде так. Вопрос. Есть ли эффективный способ проверить, представляет ли строка дату? можно очень хорошо понять, как если бы строка представляла любую дату. Возможно, это было бы лучше в качестве комментария, но это не совсем не по теме. - person yur; 07.11.2019
comment
@Joakim Danielson, хотя я понимаю, почему вы думаете, что это не ответ, я не согласен. Поскольку вы можете реализовать это решение с одним форматом в списке форматов, и если требования OP изменятся для поддержки более одного формата, его будет легко изменить без изменения кода. Поэтому я остаюсь при своем ответе. Кроме того, что касается использования Exception в коде OP, в этом случае это допустимо и приемлемо. - person Michael Gantman; 07.11.2019
comment
Я согласен, я прочитал текст, который был больше сосредоточен на использовании try/catch, и недостаточно внимательно прочитал заголовок. Таким образом, проблема больше связана с несоответствием в вопросе ОП, чем с этим ответом. удаляю свой комментарий. - person Joakim Danielson; 07.11.2019