I need to extract least dates from given dates array for every mentioned month.
example- date format is dd/MM/yyyy Following is sample input
04/11/2019, 11/11/2019, 18/11/2019, 25/11/2019, 02/12/2019, 09/12/2019,
06/01/2020, 03/02/2020, 10/02/2020, 17/02/2020, 24/02/2020, 02/03/2020,
09/03/2020, 16/03/2020, 23/03/2020, 30/03/2020, 06/04/2020, 13/04/2020,
20/04/2020, 27/04/2020
I need to get least date from each month:
output be like-
04/11/2019, 02/12/2019, 06/01/2020, 03/02/2020, 02/03/2020, 06/04/2020
Can anyone help?
The Excel EOMONTH function returns the last day of the month, n months in the past or future. You can use EDATE to calculate expiration dates, due dates, and other dates that need to land on the last day of a month.
Explaining formula in cell B8 The MIN function returns the smallest earliest date from cell range $B$3:$C$5. The dollar signs make sure that the cell reference doesn't change when we copy the cell and paste it to the cells below.
If you want to find out the latest dates in the range, you can enter the formula =MAX(A1:D7), and press the Enter key. This formula of =LARGE(A1:D7,1) will help you get the latest dates quickly.
To solve this formula, Excel first extracts the year, month, and day values from the date in B6, then adds 1 to the month value. Next, a new date is assembled by the DATE function, using the same day and year, and month + 1 for month. = DATE(YEAR(B6),MONTH(B6) + 1,DAY(B6)) = DATE(2010,1 + 1,15) = DATE(2010,2,15) = 2 / 15 / 2010
If you are using Java-8 you can use :
List<LocalDate> collect = Stream.of(strings)
.map(s -> LocalDate.parse(s, format)) // convert your strings to LocalDate
.collect(Collectors.groupingBy(YearMonth::from)) // group by year and month
.values().stream()
.map(a -> a.stream().sorted().limit(1).findFirst().get())
.sorted()
.collect(Collectors.toList()); // collect the results
outputs
[2019-11-04, 2019-12-02, 2020-01-06, 2020-02-03, 2020-03-02, 2020-04-06]
Ideone demo
public List<LocalDate> filterDates(List<LocalDate> dates) {
return dates.stream()
.collect(Collectors.groupingBy(YearMonth::from))
.values()
.stream()
.map(Collections::min) // .map(Collections::max)
.collect(Collectors.toList());
}
Instead of .map(Collections::min)
you can use the following:
.map(list -> {
list.sort(Comparator.naturalOrder());
return list.get(0);
})
Or:
.map(list -> list.stream().max(Comparator.naturalOrder()))
There’s a wealth of good answers already. On top of those I would like to add:
LocalDate
objects. If you get string input, parse it before adding to the list.In Java 10 or later:
List<LocalDate> input = List.of(LocalDate.of(2019, 11, 4),
LocalDate.of(2019, 11, 11), LocalDate.of(2019, 11, 18),
LocalDate.of(2019, 11, 25), LocalDate.of(2019, 12, 2),
LocalDate.of(2019, 12, 9), LocalDate.of(2020, 1, 6),
LocalDate.of(2020, 2, 3), LocalDate.of(2020, 2, 10),
LocalDate.of(2020, 2, 17), LocalDate.of(2020, 2, 24),
LocalDate.of(2020, 3, 2), LocalDate.of(2020, 3, 9),
LocalDate.of(2020, 3, 16), LocalDate.of(2020, 3, 23),
LocalDate.of(2020, 3, 30), LocalDate.of(2020, 4, 6),
LocalDate.of(2020, 4, 13), LocalDate.of(2020, 4, 20),
LocalDate.of(2020, 4, 27));
List<LocalDate> minDatePerMonth = input.stream()
.collect(Collectors.groupingBy(YearMonth::from, Collectors.minBy(Comparator.naturalOrder())))
.values()
.stream()
.map(Optional::orElseThrow)
.sorted()
.collect(Collectors.toList());
I am using the overloaded version of Collectors.groupingBy
that accepts a downstream collector. groupingBy
produces a map, but instead of the map values being lists they are produced by the downstream collector. In this case Collectors.minBy
, which produces Optional<LocalDate>
. And since the groupingBy
would not create a map entry without at least one date, we know that the Optional
cannot be empty.
Of course we want nicely formatted output for our user. We produce that in this way:
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd/MM/uuuu");
String output = minDatePerMonth.stream()
.map(formatter::format)
.collect(Collectors.joining(", "));
System.out.println(output);
04/11/2019, 02/12/2019, 06/01/2020, 03/02/2020, 02/03/2020, 06/04/2020
In Java 9
The no-arg Optional.orElseThrow
was introduced in Java 10. In Java 8 and 9 you may use for example:
.map(old -> old.orElseThrow(() -> new IllegalStateException("This can’t happen")))
In Java 8
List.of
was introduced in Java 9. However you said that you had already got the list, so I consider how to initialize it outside the question. I trust readers to find their way of initializing it in Java 8 if required.
Here is a sequence that you will need to do
This is your algorithm. I will leave the implementation for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With