Here is my requirement. Pretty sure there is an elegant way to do this. Need your help. I need to build a backend program to process and insert multiple dates into a table using start and end time selected by user.
Input:
StartTime: 11/26/2021 11:00 PM
EndTime: 11/28/2021 04:00 AM
Output I am expecting
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
My Code
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);
List<LocalDateTime> totalDates = new ArrayList<>();
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 < totalDates.size(); i ) {
System.out.print(totalDates.get(i) "\n");
}
}
My Output:
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
CodePudding user response:
You also need to parse the output. Therefore you can use the already defined DateTimeFormatter
, which has a parse
method.
Code for the output:
System.out.println(totalDates.get(i).format(formatter));
Also you have one additional line in your output. This one comes from the line where you set localStartTime = localStartTime.with(LocalTime.MIN);
. Here i would suggest this change:
LocalDateTime workingStartTime = localStartTime;
List<LocalDateTime> totalDates = new ArrayList<>();
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);
}
Edit: Solution using streams and flatMap
Here is how you build the final List with streams (no extra adding of the last day is needed):
List<LocalDateTime> totalDates = localStartTime.toLocalDate().datesUntil(localEndTime.toLocalDate().plusDays(1))
.flatMap(date -> 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());
CodePudding user response:
This seems to work. If there are other elegant ways to do this.. Please let me know.
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);
List<LocalDateTime> totalDates = new ArrayList<>();
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 < totalDates.size(); i ) {
System.out.print(formatter.format(totalDates.get(i)) "\n");
}
}
CodePudding user response:
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);
- Start streaming the dates as given
- then create an inner stream by creating two
LocalDateTime
instances using the currentLocalDate
instance.- current datetime by
1 minute
before midnight - current datetime by
1 day
ahead of midnight
- current datetime by
- then
flatMap
that stream and put the datetimes in a linked list. - to finish, add the current start
LocalDateTime
to the beginning of the list - and the ending
LocalDateTime
to the end of the list
List<LocalDateTime> list =
start.toLocalDate().datesUntil(end.toLocalDate())
.flatMap(date -> 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 -> System.out.println(d.format(dtf)));
prints
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