#java #time
#Ява #время
Вопрос:
Вот мое требование. Почти уверен, что есть элегантный способ сделать это. Нужна твоя помощь. Мне нужно создать серверную программу для обработки и вставки нескольких дат в таблицу, используя время начала и окончания, выбранное пользователем.
Ввод:
StartTime: 11/26/2021 11:00 PM EndTime: 11/28/2021 04:00 AM
Результат, которого я ожидаю
11/26/2021 11:00 PM 11/26/2021 11:59 PM 11/27/2021 12:00 AM 11/27/2021 11:59 PM 11/28/2021 12:00 AM 11/28/2021 04:00 AM
Мой Код
public static void main(String[] args) { String StartTime = "11/27/2021 11:00 PM"; String EndTime = "11/29/2021 04:00 AM"; DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm a"); LocalDate localStartDate = LocalDate.parse(StartTime, formatter); LocalDate localEndDate = LocalDate.parse(EndTime, formatter); LocalDateTime localStartTime = LocalDateTime.parse(StartTime,formatter); LocalDateTime localEndTime = LocalDateTime.parse(EndTime,formatter); Listlt;LocalDateTimegt; totalDates = new ArrayListlt;gt;(); while (!localStartTime.isAfter(localEndTime)) { totalDates.add(localStartTime); totalDates.add(localStartTime.with(LocalTime.MAX)); localStartTime = localStartTime.plusDays(1); localStartTime = localStartTime.with(LocalTime.MIN); } totalDates.add(localEndTime.with(LocalTime.MIN)); totalDates.add(localEndTime); for (int i = 0; i lt; totalDates.size(); i ) { System.out.print(totalDates.get(i) "n"); } }
Мой Вывод:
2021-11-27T23:00 2021-11-27T23:59:59.999999999 2021-11-28T00:00 2021-11-28T23:59:59.999999999 2021-11-29T00:00 2021-11-29T23:59:59.999999999 2021-11-29T00:00 2021-11-29T04:00
Комментарии:
1. Чего вы пытаетесь достичь с помощью MIN MAX и
plusDays
? Я сбит с толку. Если вы объясните свою цель, возможно, мы сможем лучше направлять вас. Как минимум, я подозреваю, что вам нужно узнать о Полуоткрытом подходе к определению промежутка времени.2. Я знаю полуоткрытый подход. Вот мое требование, пользователь вводит две метки времени, мне нужно преобразовать их в разные выходные данные на основе количества дней между вводом пользователем.
3. Предоставьте пояснения в виде изменений к вашему вопросу, а не в виде комментариев.
Ответ №1:
Вам также необходимо проанализировать выходные данные. Поэтому вы можете использовать уже определенный DateTimeFormatter
, у которого есть parse
метод.
Код для вывода:
System.out.println(totalDates.get(i).format(formatter));
Также у вас есть одна дополнительная строка в вашем выводе. Это происходит от линии, где вы установили localStartTime = localStartTime.with(LocalTime.MIN);
. Здесь я бы предложил это изменение:
LocalDateTime workingStartTime = localStartTime; Listlt;LocalDateTimegt; totalDates = new ArrayListlt;gt;(); while (!workingStartTime.isAfter(localEndTime)) { if(!workingStartTime.equals(localStartTime)) { workingStartTime = workingStartTime.with(LocalTime.MIN); } totalDates.add(workingStartTime); totalDates.add(workingStartTime.with(LocalTime.MAX)); workingStartTime = workingStartTime.plusDays(1); }
Изменить: Решение с использованием потоков и плоской карты
Вот как вы строите окончательный список с потоками (дополнительное добавление последнего дня не требуется):
Listlt;LocalDateTimegt; totalDates = localStartTime.toLocalDate().datesUntil(localEndTime.toLocalDate().plusDays(1)) .flatMap(date -gt; Stream.of( date.equals(localStartTime.toLocalDate()) ? LocalDateTime.of(date, localStartTime.toLocalTime()) : LocalDateTime.of(date, LocalTime.MIN), date.equals(localEndTime.toLocalDate()) ? LocalDateTime.of(date, localEndTime.toLocalTime()) : LocalDateTime.of(date, LocalTime.MAX)) ) .collect(Collectors.toList());
Комментарии:
1. По крайней мере, в вашем выводе использовался правильный порядок, основанный на ISO 8601 🙂
2. Альтернативный код для вывода:
System.out.println(totalDates.get(i).format(formatter));
3. @Гобой Thx для ввода. Адаптировал ответ на этот вопрос.
4. Решение с использованием потоков не работает. Ошибка ниже.
Cannot infer type argument(s) for lt;Rgt; flatMap(Functionlt;? super T,? extends Streamlt;? extends Rgt;gt;)
5. Ты тоже написал эту
Stream.of
роль? Это важно дляflatMap
. (работал в моей IDE)
Ответ №2:
String startTime = "11/26/2021 11:00 PM"; String endTime = "11/28/2021 04:00 AM"; DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm a"); LocalDateTime start = LocalDateTime.parse(startTime, dtf); LocalDateTime end = LocalDateTime.parse(endTime, dtf);
- Начните потоковую передачу дат, как указано
- затем создайте внутренний поток, создав два
LocalDateTime
экземпляра, используя текущийLocalDate
экземпляр.- текущая дата
1 minute
и время до полуночи - текущая дата
1 day
и время до полуночи
- текущая дата
- затем
flatMap
этот поток и поместите даты в связанный список. - чтобы закончить, добавьте текущее начало
LocalDateTime
в начало списка - и конец
LocalDateTime
в конце списка
Listlt;LocalDateTimegt; list = start.toLocalDate().datesUntil(end.toLocalDate()) .flatMap(date -gt; Stream.of( date.atTime(23,59), date.atTime(0,0).plusDays(1))) .collect(Collectors .toCollection(LinkedList::new)); list.add(0, start); list.add(end); list.forEach(d -gt; System.out.println(d.format(dtf)));
С принтами
11/26/2021 11:00 PM 11/26/2021 11:59 PM 11/27/2021 12:00 AM 11/27/2021 11:59 PM 11/28/2021 12:00 AM 11/28/2021 04:00 AM
Ответ №3:
Кажется, это работает. Если есть другие элегантные способы сделать это.. Пожалуйста, дайте мне знать.
public static void main(String[] args) { String StartTime = "02/27/2021 11:00 PM"; String EndTime = "03/02/2021 01:00 PM"; DateTimeFormatter formatter = DateTimeFormatter.ofPattern("MM/dd/yyyy hh:mm a"); LocalDate localStartDate = LocalDate.parse(StartTime, formatter); LocalDate localEndDate = LocalDate.parse(EndTime, formatter); LocalDateTime localStartTime = LocalDateTime.parse(StartTime, formatter); LocalDateTime localEndTime = LocalDateTime.parse(EndTime, formatter); Listlt;LocalDateTimegt; totalDates = new ArrayListlt;gt;(); while (localEndDate.isAfter(localStartDate)) { totalDates.add(localStartTime); totalDates.add(localStartTime.with(LocalTime.MAX)); if (!localStartDate.equals(localEndDate)) { localStartTime = localStartTime.plusDays(1).with(LocalTime.MIN); } localStartDate = localStartDate.plusDays(1); } totalDates.add(localEndTime.with(LocalTime.MIN)); totalDates.add(localEndTime); for (int i = 0; i lt; totalDates.size(); i ) { System.out.print(formatter.format(totalDates.get(i)) "n"); } }