Я хочу преобразовать дату из String в LocalDateTime с помощью DateTimeFormatterBuilder ()

не преобразует последнюю цифру даты под индексом 16 в

      private LocalDateTime parseDate(String date) {
dateOut = LocalDateTime.parse(date, fmt);

появляется ошибка:

java.time.format.DateTimeParseException: текст '27 апр 21, 01:42'не может быть проанализирован в индексе 16

Я не могу найти ответ.

      public class HtmlParse {

    private LocalDateTime lastDate = null;
    private LocalDateTime dateTime = null;
    private DateTimeFormatter fmt = new DateTimeFormatterBuilder()
            .appendPattern("d ")
            .appendText(ChronoField.MONTH_OF_YEAR, new HashMap<>() { {
                put(1L, "янв"); put(2L,  "фев"); put(3L,  "мар"); put(4L,  "апр");
                put(5L, "май"); put(6L,  "июн"); put(7L,  "июл"); put(8L,  "авг");
                put(9L, "сен"); put(10L, "окт"); put(11L, "ноя"); put(12L, "дек");
            } })
            .appendPattern(" yy, HH:mm")
            .toFormatter(new Locale("ru"));

    public void setLastDate(LocalDateTime lastDate) {
        this.lastDate = lastDate;
    }

    private LocalDateTime parseDate(String date) {
        LocalDateTime dateOut;
        if (date.contains("сегодня")) {
            dateOut = LocalDateTime.of(
                    LocalDate.now(),
                    LocalTime.parse(date.split(" ")[1])
            );
        } else if (date.contains("вчера")) {
            dateOut = LocalDateTime.of(
                    LocalDate.now().minusDays(1L),
                    LocalTime.parse(date.split(" ")[1])
            );
        } else {
            dateOut = LocalDateTime.parse(date, fmt);
        }
        return dateOut;
    }

    private boolean filter(String namePage) {
        return Pattern.compile("(java)(?!\\s?script)", Pattern.CASE_INSENSITIVE).matcher(namePage).find();
    }

    private String nextPageLink(Document doc) {
        int current = Integer.parseInt(doc.select("table.sort_options td b").text());
        return doc.select(String.format("table.sort_options td a:contains(%s)", current + 1)).attr("href");
    }

    @Override
    public Post detail(String postLink) {
        Post post = null;
        try {
            Document doc = Jsoup.connect(postLink).get();
            String name = doc.title().split(" / Вакансии")[0];
            String text = doc.select("td.msgBody").get(1).text();
            String date = doc.select("td.msgFooter").get(0).text();
            this.dateTime = this.parseDate(date.substring(0, date.indexOf("[")));
            post = new Post(name, text, dateTime, postLink);
        } catch (IOException e) {
            LOG.error(e.getMessage(), e);
        }
        return post;
    }

    @Override
    public List<Post> parser(String linkPage) {
        LOG.info("Start parsing...");
        List<Post> posts = new ArrayList<>();
        try {
            exitlabel: do {
                Document doc = Jsoup.connect(linkPage).get();
                Elements table = doc.select("table.forumtable tr:has(td)");
                for (Element tr : table) {
                    Elements td = tr.select("td");
                    String namePage = td.get(1).text();
                    String datePage = td.get(5).text();
                    if (this.filter(namePage)) {
                        LocalDateTime date = this.parseDate(datePage);
                        if (lastDate != null && lastDate.isAfter(date)) {
                            break exitlabel;
                        }
                        String hrefPost = td.get(1).select("a").attr("href");
                        Post post = this.detail(hrefPost);
                        if (dateTime.isAfter(lastDate)) {
                            posts.add(post);
                        }
                    }
                }
                linkPage = this.nextPageLink(doc);
            } while (!linkPage.isEmpty());
            Collections.sort(posts);
        } catch (IOException e) {
            LOG.error(e.getMessage(), e);
        }
        LOG.info(String.format("%s posts found.", posts.size()));
        return posts;
    }

    public static void main(String[] args) throws SchedulerException {
        String link = "https://www.sql.ru/forum/job-offers/";
        HtmlParse htmlParse = new HtmlParse();
        htmlParse.setLastDate(LocalDateTime.of(2020, 1, 1, 0, 0));
        List<Post> list = htmlParse.parser(link);
        for (Post p : list) {
            System.out.println(p);
        }
    }
}

1 ответ

Как я прокомментировал ниже, причиной проблемы является добавление пробелов в конце шаблона. Заменять .appendPattern(" yy, HH:mm ") с участием .appendPattern(" yy, HH:mm") чтобы заставить его работать.

Кроме того, если вы используете Java SE 9, я рекомендую вам использовать Map#ofEntries​ для инициализации Map.

Демо:

      import static java.util.Map.entry;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.DateTimeFormatterBuilder;
import java.time.temporal.ChronoField;
import java.util.Locale;
import java.util.Map;

public class Main {
    public static void main(String args[])  {
        DateTimeFormatter fmt = new DateTimeFormatterBuilder()
                .appendPattern("d ")
                .appendText(ChronoField.MONTH_OF_YEAR, Map.ofEntries(
                    entry(1L, "янв"), entry(2L,  "фев"), entry(3L,  "мар"), entry(4L,  "апр"),
                    entry(5L, "май"), entry(6L,  "июн"), entry(7L,  "июл"), entry(8L,  "авг"),
                    entry(9L, "сен"), entry(10L, "окт"), entry(11L, "ноя"), entry(12L, "дек")
                ))
                .appendPattern(" yy, HH:mm")
                .toFormatter(new Locale("ru"));
        
        LocalDateTime ldt = LocalDateTime.parse("27 апр 21, 01:42", fmt);
        System.out.println(ldt);
    }
}

Выход:

      2021-04-27T01:42
Другие вопросы по тегам