Разбор недели, час и минута - PullRequest
1 голос
/ 30 апреля 2020

Я пытаюсь загрузить из XML поле расписания, которое выглядит следующим образом: «ПН 17:20»

Я хочу избежать синтаксического анализа вручную с помощью строки замены et c. Я проверил онлайн для этого кода

final String dateInString = "Mon, 05 May 1980";
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE, d MMM yyyy", Locale.ENGLISH);
final LocalDate dateTime = LocalDate.parse(dateInString, formatter);

Но у него нет поля недели (я не могу получить неделю). Есть ли подобная система короткого разбора?

Ответы [ 4 ]

1 голос
/ 01 мая 2020

Конечно, это возможно с помощью Java 8 Date & Time API.

Похоже, у вас есть три поля: день недели, час дня и минута час. Обычно это можно проанализировать, используя DateTimeFormatter::ofPattern со строкой форматирования EEE HH:mm, но проблема в том, что MON (во всех заглавных буквах) не является стандартным; вместо него должно быть Mon.

Поэтому нам нужно собрать наш форматер, используя DateTimeFormatterBuilder, инструктируя, что строка должна быть проанализирована без учета регистра:

DateTimeFormatter formatter = new DateTimeFormatterBuilder()
    .parseCaseInsensitive()
    .appendPattern("EEE HH:mm")
    .toFormatter(Locale.ROOT);

Единственное, что нужно сделать, это проанализировать поля, используя

TemporalAccessor parsed = formatter.parse(elem);

Теперь parsed содержит вышеупомянутые проанализированные поля.

К дате / времени

Конечно, вы не t есть , чтобы преобразовать это в фактическую дату. Есть много случаев использования, когда не требуется дата, а скорее день недели и время. Это пример .

Но если вы, например, хотите получить текущую дату и настроить ее так, чтобы она соответствовала данным вашего расписания, вы можете сделать что-то вроде этого:

TemporalAdjuster adj = TemporalAdjusters.nextOrSame(DayOfWeek.of(parsed.get(ChronoField.DAY_OF_WEEK)));
LocalDateTime now = LocalDate.now()
    .atTime(LocalTime.from(parsed))
    .with(adj);
1 голос
/ 01 мая 2020

Попробуйте это.

final String dateInString = "Thu Apr 30, 2020 17:20";
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("EEE MMM dd, yyyy HH:mm");
final LocalDateTime dateTime = LocalDateTime.parse(dateInString, formatter);
System.out.println(dateTime);

Вышеприведенный синтаксический анализ этого.

2020-04-30T17:20

Если вы хотите неделю, вы можете сделать это.

System.out.println(dateTime.get(ChronoField.ALIGNED_WEEK_OF_MONTH));
System.out.println(dateTime.get(ChronoField.ALIGNED_WEEK_OF_YEAR));

Печать

5
18

Обновленный ответ.

final String dateInString ="MON 17:20";
String[] vals = dateInString.split("\\s+");
final DateTimeFormatter formatter = DateTimeFormatter.ofPattern("HH:mm");
final LocalTime dateTime = LocalTime.parse(vals[1], formatter);
System.out.println(vals[0] + " " + dateTime);

Отпечатки

MON 17:20

Подробности читайте на ChronoField
Проверьте java .time пакет для получения дополнительной информации о Java Временных возможностях.

0 голосов
/ 01 мая 2020

Проблема не в том, что трудно разобрать, используя DateTimeFormatter. Проблема в том, что у нас нет хорошего типа для анализа. Например, информация не помещается в LocalDate или LocalDateTime. И в зависимости от того, что вам нужно для вашего планировщика, я думаю, что решение состоит в том, чтобы разобрать два объекта вместо одного: день недели и время дня.

    DateTimeFormatter formatter = new DateTimeFormatterBuilder()
            .parseCaseInsensitive()
            .appendPattern("EEE H:mm")
            .toFormatter(Locale.ENGLISH);

    String scheduleString = "MON 17:20";

    TemporalAccessor parsed = formatter.parse(scheduleString);
    DayOfWeek dow = DayOfWeek.from(parsed);
    LocalTime time = LocalTime.from(parsed);

    System.out.format("Schedule: every %s at %s", dow, time);

Вывод:

Расписание: каждый понедельник в 17: 20

Явное использование интерфейса TemporalAccessor считается низкоуровневым, но я предпочитаю это решение вместо String.replace() или String.split(). Если вы хотите избежать низкоуровневого интерфейса, просто проанализируйте строку дважды, один раз в DayOfWeek и один раз в LocalTime.

0 голосов
/ 01 мая 2020

Вам необходимо передать свой объект LocalDate в приведенный ниже пример: Получить номер недели LocalDate (Java 8)

Это должно получить его для вас.

Из приведенной выше ссылки передайте поле dateTime в коде, например ...

    TemporalField woy = WeekFields.of(Locale.getDefault()).weekOfWeekBasedYear(); 
int weekNumber = dateTime.get(woy);

В зависимости от вашей локали и того, где будет выполняться этот код, вы можете рассмотреть WeekFields.ISO, как указано в ссылка выше.

...