Я хочу преобразовать дату из 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