java.time.format.DateTimeParseException: текст не может быть проанализирован по индексу 3

Я использую Java 8 для анализа даты и определения разницы между двумя датами.

Вот мой фрагмент:

String date1 ="01-JAN-2017";
String date2 = "02-FEB-2017";

DateTimeFormatter df = DateTimeFormatter .ofPattern("DD-MMM-YYYY", en);
LocalDate  d1 = LocalDate.parse(date1, df);
LocalDate  d2 = LocalDate.parse(date2, df);

Long datediff = ChronoUnit.DAYS.between(d1,d2);

Когда я бегу, я получаю ошибку:

java.time.format.DateTimeParseException: текст не может быть проанализирован по индексу 3

Ответ 1

Следующий код работает. Проблема в том, что вы используете "JAN" вместо "Jan". DateTimeFormatter не признает, что это похоже. а также изменить шаблон на "d-MMM-yyyy".

  String date1 ="01-Jan-2017";
  String date2 = "02-Feb-2017";

  DateTimeFormatter df = DateTimeFormatter.ofPattern("d-MMM-yyyy");
  LocalDate  d1 = LocalDate.parse(date1, df);
  LocalDate  d2 = LocalDate.parse(date2, df);

  Long datediff = ChronoUnit.DAYS.between(d1,d2);  

Источник: https://www.mkyong.com/java8/java-8-how-to-convert-string-to-localdate/

Ответ 2

Прежде всего, проверьте javadoc. Заглавная буква D представляет поле дня (не день месяца, как вы хотите), а верхний регистр Y представляет поле недели за неделю (а не год, как вы хотите). Правильными шаблонами являются строчные буквы d и y.

Кроме того, вы используете месячные имена заглавными буквами (JAN и FEB), поэтому ваш форматировщик должен быть нечувствительным к регистру (поведение по умолчанию - принимать только значения, такие как Jan и Feb). И эти месячные имена являются английскими сокращениями, поэтому вы также должны использовать английский язык, чтобы убедиться, что он правильно разбирает имена (используя класс java.util.Locale).

Итак, ваш форматировщик должен быть создан следующим образом:

DateTimeFormatter df = new DateTimeFormatterBuilder()
    // case insensitive to parse JAN and FEB
    .parseCaseInsensitive()
    // add pattern
    .appendPattern("dd-MMM-yyyy")
    // create formatter (use English Locale to parse month names)
    .toFormatter(Locale.ENGLISH);

Это заставит ваш код работать (и datediff будет 32).

Ответ 3

Может быть, вы можете использовать этот шаблон,

 String d2arr[] = {
            "2016-12-21",
            "1/17/2016",
            "1/3/2016",
            "11/23/2016",
            "OCT 20 2016",
            "Oct 22 2016",
            "Oct 23", // default year is 2016
            "OCT 24",  // default year is 2016
    };

    DateTimeFormatterBuilder builder = new DateTimeFormatterBuilder()
            .parseCaseInsensitive().parseLenient()
            .parseDefaulting(ChronoField.YEAR_OF_ERA, 2016L)
            .appendPattern("[yyyy-MM-dd]")
            .appendPattern("[M/dd/yyyy]")
            .appendPattern("[M/d/yyyy]")
            .appendPattern("[MM/dd/yyyy]")
            .appendPattern("[MMM dd yyyy]");

    DateTimeFormatter formatter2 = builder.toFormatter(Locale.ENGLISH);

https://coderanch.com/t/677142/java/DateTimeParseException-Text-parsed-unparsed-textвведите описание ссылки здесь

Ответ 4

// DateTimeFormatterBuilder provides custom way to create a
    // formatter
    // It is Case Insensitive, Nov , nov and NOV will be treated same
    DateTimeFormatter f = new DateTimeFormatterBuilder().parseCaseInsensitive()
            .append(DateTimeFormatter.ofPattern("yyyy-MMM-dd")).toFormatter();
    try {
        LocalDate datetime = LocalDate.parse("2019-DeC-22", f);
        System.out.println(datetime); // 2019-12-22
    } catch (DateTimeParseException e) {
        // Exception handling message/mechanism/logging as per company standard
    }