-1

Hi I am looking for a quick and compact way to get the latest date from an ArrayList<String> of dates which have the following format (I intend to generate this from a database). The content of the ArrayList will have the below format

ArrayList<String> datelist=new ArrayList<String>(); 
datelist.add("October 09, 2019");
datelist.add("August 20, 2018");
datelist.add("October 09, 2019");
datelist.add("August 31, 2019");

the end result should be a string like October 09, 2019 any ideas regarding functions or logic will be appreciated

EDIT: Thank you all for your suggestions :). Since I needed a generic solution for a bunch of raw data processing (as it turned out while trying all your suggestions) and the above was a sample data ...issues like date mentioned in other languages as mention by @deHaar cropped up and the approach suggested by @Eritrean was most suitable for me

Afrah_Rahman
  • 115
  • 7
  • 5
    Parse the strings to date objects, preferable `LocalDate` objects, then find the max date. For a compact way, do it with streams. Format back to string, if needed. – Andreas Oct 10 '19 at 11:43
  • use an ordered collection, implement comparator and take the last/first one – vmrvictor Oct 10 '19 at 11:44
  • If you're using a java.util.Date format then you can just iterate over the list and i think there's a method called parseDate() or something – J. Lengel Oct 10 '19 at 11:47
  • Listen to what @Andreas said: Parse the `String`s to `LocalDate`s, which are comparable. – deHaar Oct 10 '19 at 11:50
  • 1
    You shouldn’t put strings into your list in the first place. Create an `ArrayList` and parse the strings into `LocalDate` objects *before* adding them to the list. It will make everything easier, and in particular finding the latest will be *very* easy. – Ole V.V. Oct 10 '19 at 11:59
  • 1
    Related: [How to find Max Date in List?](https://stackoverflow.com/questions/20995664/how-to-find-max-date-in-listobject) and [How to sort Date which is in string format in java?](https://stackoverflow.com/questions/14451976/how-to-sort-date-which-is-in-string-format-in-java) – Ole V.V. Oct 10 '19 at 12:04

6 Answers6

2

An Example to get max date from the list of dates

Convert your List of String to List of LocalDate and the rest of the operations will be taken care of by the below code.

LocalDate maxDate = dates.stream()
                            .max( Comparator.comparing( LocalDate::toEpochDay ) )
                            .get();

LocalDate minDate = dates.stream()
                            .min( Comparator.comparing( LocalDate::toEpochDay ) )
                            .get();
Dinesh K
  • 269
  • 2
  • 8
1

As already mentioned in the comments, something similar to the one below should work:

    ArrayList<String> datelist=new ArrayList<>(); 
        datelist.add("October 09, 2019");
        datelist.add("August 20, 2018");
        datelist.add("October 09, 2019");
        datelist.add("August 31, 2019");

        DateTimeFormatter dtf = DateTimeFormatter.ofPattern("MMMM dd, yyyy", Locale.US);
        String maxDate = datelist.stream()
                .map(d -> LocalDate.parse(d, dtf))
                .max(Comparator.comparing(LocalDate::toEpochDay))
                .get().format(dtf);
        System.out.println(maxDate);
Eritrean
  • 15,851
  • 3
  • 22
  • 28
1

Don’t put strings into your list. Put LocalDate objects. Just like you wouldn’t store numbers as strings in a list (I hope).

Also I found the code in some of the other answers a bit wordy. With LocalDate objects in the list finding the latest date can be done in one line.

    DateTimeFormatter dateFormatter = DateTimeFormatter.ofPattern("MMMM dd, uuuu", Locale.ENGLISH);

    List<LocalDate> dateList = new ArrayList<>(); 
    dateList.add(LocalDate.parse("October 09, 2019", dateFormatter));
    dateList.add(LocalDate.parse("August 20, 2018", dateFormatter));
    dateList.add(LocalDate.parse("October 09, 2019", dateFormatter));
    dateList.add(LocalDate.parse("August 31, 2019", dateFormatter));

    LocalDate latest = Collections.max(dateList);
    System.out.println("End result: " + latest.format(dateFormatter));

Output from this snippet is:

End result: October 09, 2019

Since the month names are in English, we should provide an English-speaking locale to make sure that the code works on all JVMs regardless of default locale setting.

Collections.max will throw NoSuchElementException if the list is empty.

If you cannot afford to change the list to contain LocalDate objects just now, using the same formatter as before:

    String latest = Collections.max(datelist,
            Comparator.comparing(s -> LocalDate.parse(s, dateFormatter)));
    System.out.println("End result: " + latest);

The output is the same as before.

Ole V.V.
  • 81,772
  • 15
  • 137
  • 161
0

Your format is "MMMM dd, yyyy"

  DateTimeFormatter format = DateTimeFormatter.ofPattern("MMMM dd, yyyy");
  Optional<LocalDate> latest = datelist.stream()
            .map(format::parse)
            .map(p -> LocalDate.of(p.get(ChronoField.YEAR), p.get(ChronoField.MONTH_OF_YEAR), p.get(ChronoField.DAY_OF_MONTH)))
            .max(LocalDate::compareTo);
  String output = latest.map(format::format).orElse("no elements");
lotor
  • 1,060
  • 7
  • 18
  • 2
    Please don’t teach the young ones to use the long outdated and notoriously troublesome `SimpleDateFormat` class. At least not as the first option. And not without any reservation. Today we have so much better in [`java.time`, the modern Java date and time API,](https://docs.oracle.com/javase/tutorial/datetime/) and its `DateTimeFormatter`. – Ole V.V. Oct 10 '19 at 11:57
0

You can convert / parse the date Strings into comparable objects and then easily find the maximum (newest / most recent date):

public static void main(String[] args) {
    // provide a list of sample data
    List<String> datelist = new ArrayList<String>();
    datelist.add("October 09, 2019");
    datelist.add("August 20, 2018");
    datelist.add("October 09, 2019");
    datelist.add("August 31, 2019");

    // create a list of LocalDates
    List<LocalDate> localDates = new ArrayList<>();

    datelist.forEach(date -> {
        // parse every String in the datelist using a matching pattern
        LocalDate localDate = LocalDate.parse(date, DateTimeFormatter.ofPattern("MMMM dd, yyyy"));
        // and add each resulting LocalDate to the list of LocalDates
        localDates.add(localDate);
    });

    // find the most recent LocalDate (the maximum here)
    LocalDate mostRecentDate = localDates.stream().max(LocalDate::compareTo).get();
    // and print it in the ISO format (or the one of your choice
    System.out.println(mostRecentDate.format(DateTimeFormatter.ISO_LOCAL_DATE));
}

Worth mentioning: This failed on my (German) system, because a LocalDate in Germany doesn't know the month October but Oktober instead. I replaced the 'c' in that month and it worked.
That means your system has to be English in order to make this code work.

EDIT
The problem with the locale is perfectly solved in the answer given by @Eritrean, which uses a DateTimeFormatter.ofPattern("MMMM dd, yyyy", Locale.US);.

deHaar
  • 17,687
  • 10
  • 38
  • 51
0

Try using LocalDate with DateTimeFormatter:

DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("MMMM dd, yyyy");
String maxDate = datelist.stream()
        .map(str -> LocalDate.parse(str, dateTimeFormatter))
        .max(LocalDate::compareTo)
        .map(dateTimeFormatter::format)
        .orElse("N/A");
Mushif Ali Nawaz
  • 3,707
  • 3
  • 18
  • 31