Запретить SimpleDateFormat сопоставлять строки с внешними символами

Если вы используете его локально и хотите выполнить код:

python -m pdb script.py

0
задан YCF_L 13 July 2018 в 21:25
поделиться

2 ответа

Если вы прочитали документацию, то есть javadoc из parse , вы увидите:

Проводит текст с начала данной строки, чтобы произвести свидание. Метод может не использовать весь текст данной строки.

Подробнее см. Метод parse(String, ParsePosition) .

Javadoc другого метода говорит:

Параметры:

source - Строка даты / времени, подлежащая анализу

pos - на входе - позиция, в которой начнется синтаксический анализ; на выходе, позиция, в которой завершился синтаксический анализ, или начальная позиция, если синтаксический анализ не был выполнен.

Итак, чтобы весь текст соответствовал формату даты, используйте второй метод и проверьте окончание parse position

Это также имеет положительный эффект от использования исключений для потока управления .

private static boolean isDate(String val) {
    String trimmedVal = val.trim();

    //These are the only formats dates will have
    String[] formatList = {"MM/dd/yyyy", "MM-dd-yyyy", "MMM/dd/yyyy", "dd-MMM-yyyy"};
    SimpleDateFormat dateFormat = new SimpleDateFormat();
    dateFormat.setLenient(false);

    ParsePosition pos = new ParsePosition(0);
    for (String str : formatList) {
        pos.setIndex(0);
        dateFormat.applyPattern(str);
        dateFormat.parse(trimmedVal, pos);
        if (pos.getIndex() == trimmedVal.length())
            return true; // full text parsed without error
    }
    return false;
}

Тест

System.out.println(isDate("12/31/2018"));
System.out.println(isDate("12-31-2018"));
System.out.println(isDate("Dec/31/2018"));
System.out.println(isDate("31-Dec-2018"));
System.out.println(isDate("4/05/2013"));
System.out.println(isDate("4/05/2013 23:54"));

Выход

true
true
true
true
true
false
2
ответ дан Andreas 17 August 2018 в 12:11
поделиться

Я хотел бы использовать java.time API из Java8 + только с одним шаблоном:

private boolean isDate(String dateString) {
    DateTimeFormatter format =
            DateTimeFormatter.ofPattern(
                    "[M/d/uuuu][M-d-uuuu][MMM/d/uuuu][d-MMM-uuuu]"
            );
    try {
        LocalDate.parse(dateString, format);
        return true;
    }catch (DateTimeParseException e){
        return false;
    }
}

, где [M/d/uuuu][M-d-uuuu][MMM/d/uuuu][d-MMM-uuuu] означает совпадение с M/d/uuuu или M-d-uuuu или MMM/d/uuuu или d-MMM-uuuu

3
ответ дан YCF_L 17 August 2018 в 12:11
поделиться
  • 1
    С помощью DateTimeFormatter вы должны использовать uuuu вместо yyyy. – Andreas 13 July 2018 в 19:51
  • 2
    Быстрый поиск Я нашел ваш ответ здесь stackoverflow.com/questions/41177442/… Я не знаю об этом @ Andreas, спасибо за информацию, которую я отредактирую, и +1 для подробного ответа – YCF_L 13 July 2018 в 19:53
  • 3
    @Andreas ИМХО, это только мягкий «должен». Чаще всего это делается, но, строго говоря, это зависит от требований, и в 99% случаев это не имеет значения на практике. Если yyyy работает так, как должно, в этом ответе тоже. – Ole V.V. 13 July 2018 в 19:54
  • 4
    Привет @ OleV.V. ваши комментарии заставляют меня ждать и искать больше об этом – YCF_L 13 July 2018 в 19:56
  • 5
    Я думаю, вы имели в виду catch блок, чтобы быть return false;, в противном случае тип возврата boolean имеет мало смысла. Кроме того, похоже, что OP ожидает, что 4/05/2013 вернет true, что происходит с SimpleDateFormat, но не происходит с вашим кодом. dd анализирует только двузначные значения. Используйте d для разбора 1-значных значений, т. Е. Шаблон должен быть "[M/d/uuuu][M-d-uuuu][MMM/d/uuuu][d-MMM-uuuu]" – Andreas 13 July 2018 в 20:00
Другие вопросы по тегам:

Похожие вопросы: