Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to sort dates in a string array in Java?

I want to create a date array and sort it. This is how I was able to do it but this is not what I required.

   java.text.SimpleDateFormat sdf = new java.text.SimpleDateFormat("dd-MM-yyyy");
   java.util.Date date1 = sdf.parse("05-03-2014");
   java.util.Date date2 = sdf.parse("23-08-2014");
   java.util.Date dates[] = {date1, date2};
   java.util.Arrays.sort(dates);
   System.out.println(java.util.Arrays.toString(dates));

Because I have a String array "String dates[] = {"05-11-2014", "23-08-2014","05-02-2013"};" So I have to sort the dates in the string array. How do I change my code?

like image 982
udeshplus Avatar asked Jan 10 '23 21:01

udeshplus


2 Answers

The better way would be to convert the String array to an array of Date

Date[] arrayOfDates = new Date[dates.length];
for (int index = 0; index < dates.length; index++) {
    arrayOfDates[index] = sdf.parse(dates[index]);
}

Then sort the arrayOfDates and if you need to, use the SimpleDateFormat to format the results back to the dates array...

Arrays.sort(arrayOfDates);
for (int index = 0; index < dates.length; index++) {
    dates[index] = sdf.format(arrayOfDates[index]);
}

This provides you with much more control over what you should do if one or more of the values in the dates array is an invalid format.

Another, "dirty" solution, would be to use a custom Comparator that would convert the values to a Date inline and compare them.

This is okay if you can guarantee the validity of the dates, but starts to fall apart when you can't, for example...

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Arrays;
import java.util.Comparator;
import java.util.logging.Level;
import java.util.logging.Logger;

public class DirtySort {

    public static void main(String[] args) {
        String dates[] = {"05-11-2014", "23-08-2014","05-02-2013"};
        Arrays.sort(dates, new Comparator<String>() {
            private SimpleDateFormat sdf = new java.text.SimpleDateFormat("dd-MM-yyyy");
            @Override
            public int compare(String o1, String o2) {
                int result = -1;

                try {
                    result = sdf.parse(o1).compareTo(sdf.parse(o2));
                } catch (ParseException ex) {
                    ex.printStackTrace();
                }

                return result;
            }
        });

        for (String date : dates) {
            System.out.println(date);
        }
    }

}
like image 120
MadProgrammer Avatar answered Jan 15 '23 14:01

MadProgrammer


Use Date-Time Type

The answer by MadProgrammer is correct. When working with date-time values, work with them as date-time data types. That's generally best. If you had a bunch of strings representing numbers, wouldn't you convert to numeric data types for your business logic?

Avoid java.util.Date

My only improvement to the other answer is to advise against using java.util.Date. Both that class and .Calendar that are bundled with Java are notoriously troublesome and should be avoided.

Instead use the Joda-Time library or the new java.time package in Java 8 inspired by Joda-Time.

Date-Only

Both Joda-Time and java.time offer a LocalDate class to handle a date-only value without any time-of-day or time zone. Just the thing for this Question.

Joda-Time

We use a DateTimeFormatter to parse the string by calling parseLocalDate. If you do not trust your data source, trap for IllegalArgumentException.

Here is some code using Joda-Time 2.4.

List<LocalDate> list = new ArrayList<LocalDate>();
DateTimeFormatter formatter = DateTimeFormat.forPattern( "dd-MM-yyyy" );
String dates[] = { "05-11-2014" , "23-08-2014" , "05-02-2013" };
for ( String string : dates ) {
    LocalDate localDate = formatter.parseLocalDate( string );
    list.add( localDate );
}
Collections.sort( list );

Dump to console. Output in original format.

System.out.println( "list: " + list );

StringBuilder output = new StringBuilder( "Localized sorted list of dates: " );
for ( LocalDate localDate : list ) {
    output.append( formatter.print( localDate ) ).append( " | " );
}
System.out.println( output );

When run.

list: [2013-02-05, 2014-08-23, 2014-11-05]
Localized sorted list of dates: 05-02-2013 | 23-08-2014 | 05-11-2014 | 

Or, using the new Java 8 syntax with lambdas. Not really sure if that's an improvement or not.

List<LocalDate> list = new ArrayList<>();
DateTimeFormatter formatter = DateTimeFormat.forPattern( "dd-MM-yyyy" );
String[] dateStringsArray = { "05-11-2014" , "23-08-2014" , "05-02-2013" };
List<String> dateStringsList = new ArrayList<>( Arrays.asList( dateStringsArray ) );
dateStringsList.stream().map( ( string ) -> formatter.parseLocalDate( string ) ).forEach( ( localDate ) -> {
    list.add( localDate );
} );
Collections.sort( list );

System.out.println( "list: " + list );

StringBuilder output = new StringBuilder( "Localized sorted list of dates: " );
list.stream().forEach( ( localDate ) -> {
    output.append( formatter.print( localDate ) ).append( " | " );
} );
System.out.println( output );
like image 40
Basil Bourque Avatar answered Jan 15 '23 13:01

Basil Bourque