Android - How to sort arrayList by date?

16,370

Solution 1

Do sorting after parsing the date.

Collections.sort(notificationList, new Comparator<Notification>() {
            DateFormat f = new SimpleDateFormat("dd/MM/yyyy '@'hh:mm a");
            @Override
            public int compare(Notification lhs, Notification rhs) {
                try {
                    return f.parse(lhs.getDate()).compareTo(f.parse(rhs.getDate()));
                } catch (ParseException e) {
                    throw new IllegalArgumentException(e);
                }
            }
        })

If your date is in some other format, write the DateFormat accordingly.

Solution 2

Consider storing the date in Notification as a long (unix time) or a Date (LocalDateTime if you're using Java 8 support) and formatting it as a String only when displaying it to the UI.

Solution 3

You can simply parse the date-time strings into LocalDateTime and perform a natural sorting.

Using Stream:

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Locale;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("d MMM u 'at' h:m a", Locale.UK);
        
        Stream.of(
                    "10 Jul 2017 at 10:59 pm",
                    "10 Jul 2017 at 10:59 pm",
                    "11 Jul 2017 at 11:15 pm",
                    "9 Jul 2017 at 11:15 pm"
                )
                .map(s -> LocalDateTime.parse(s, dtf))
                .sorted()
                .forEach(dt -> System.out.println(dtf.format(dt)));
    }
}

Output:

9 Jul 2017 at 11:15 pm
10 Jul 2017 at 10:59 pm
10 Jul 2017 at 10:59 pm
11 Jul 2017 at 11:15 pm

Non-Stream solution:

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Locale;

public class Main {
    public static void main(String[] args) {
        final DateTimeFormatter dtf = DateTimeFormatter.ofPattern("d MMM u 'at' h:m a", Locale.UK);
        List<LocalDateTime> listLdt = new ArrayList<>();
        
        List<String> listDtStr = 
                Arrays.asList(
                                "10 Jul 2017 at 10:59 pm",
                                "10 Jul 2017 at 10:59 pm",
                                "11 Jul 2017 at 11:15 pm",
                                "9 Jul 2017 at 11:15 pm"
                            );
        
        // Add the strings, parsed into LocalDateTime, to listLdt
        for(String s: listDtStr) {
            listLdt.add(LocalDateTime.parse(s, dtf));
        }
        
        // Sort listLdt
        Collections.sort(listLdt);
        
        // Display
        for(LocalDateTime ldt: listLdt) {
            System.out.println(ldt.format(dtf));
        }
    }
}

Output:

9 Jul 2017 at 11:15 pm
10 Jul 2017 at 10:59 pm
10 Jul 2017 at 10:59 pm
11 Jul 2017 at 11:15 pm

Learn more about the modern date-time API from Trail: Date Time.

Using legacy date-time API:

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Locale;

public class Main {
    public static void main(String[] args) throws ParseException {
        final SimpleDateFormat sdf = new SimpleDateFormat("d MMM u 'at' h:m a", Locale.UK);
        List<Date> listDate = new ArrayList<>();
        
        List<String> listDtStr = 
                Arrays.asList(
                                "10 Jul 2017 at 10:59 pm",
                                "10 Jul 2017 at 10:59 pm",
                                "11 Jul 2017 at 11:15 pm",
                                "9 Jul 2017 at 11:15 pm"
                            );
        
        // Add the strings, parsed into LocalDateTime, to listDate
        for(String s: listDtStr) {
            listDate.add(sdf.parse(s));
        }
        
        // Sort listDate
        Collections.sort(listDate);
        
        // Display
        for(Date date: listDate) {
            System.out.println(sdf.format(date));
        }
    }
}

Output:

9 Jul 4 at 11:15 pm
10 Jul 5 at 10:59 pm
10 Jul 5 at 10:59 pm
11 Jul 6 at 11:15 pm

Note: The java.util date-time API and their formatting API, SimpleDateFormat are outdated and error-prone. It is recommended to stop using them completely and switch to the modern date-time API* .


* For any reason, if you have to stick to Java 6 or Java 7, you can use ThreeTen-Backport which backports most of the java.time functionality to Java 6 & 7. If you are working for an Android project and your Android API level is still not compliant with Java-8, check Java 8+ APIs available through desugaring and How to use ThreeTenABP in Android Project.

Solution 4

As I understand, Notification.getDate() returns String value. So, use

public static Date toDate(String value) throws ParseException {
    DateFormat format = new SimpleDateFormat("d MMMM yyyy 'at' HH:mm'am'", Locale.ENGLISH);
    return format.parse(value);
}

this method to det Date from your String. Just get two dates and use Date.compareTo method.

date1 = toDate(lhs.getDate());
date2 = toDate(rhs.getDate());
date1.compareTo(date2);
Share:
16,370
arsenallavigne
Author by

arsenallavigne

Updated on June 27, 2022

Comments

  • arsenallavigne
    arsenallavigne almost 2 years

    I'm trying to sort my arrayList by date. I stored the date on Firebase each time I receive a notification and is retrieved from there. I'm using Collections.sort but I don't know how to implement onto my codes as my date format starts with a number in a string format like "12 Jul 2017 at 12:00am".

    I've seen some examples of this on stackoverflow but I don't know how to make it work in my case. I will post screenshots and my codes below.

    The dates are not sorted.

    enter image description here

    NotificationFragment.java

    public class NotificationFragment extends Fragment {
            prepareNotification1();
            sortDate();
            return v;
        }
    
           private void prepareNotification1() {
                FirebaseUser user = FirebaseAuth.getInstance().getCurrentUser();
                String userID = user.getUid();
    
      mRef.child("customers").child(userID).child("Notification").addChildEventListener(new ChildEventListener() {
                @Override
                public void onChildAdded(DataSnapshot dataSnapshot, String s) {
                        Notification menu = dataSnapshot.getValue(Notification.class);
                        notificationList.add(menu);
                    mAdapter.notifyDataSetChanged();
                }
     });
        }
    
        public void sortDate() {
            Collections.sort(notificationList, new Comparator<Notification>() {
                @Override
                public int compare(Notification lhs, Notification rhs) {
                    return lhs.getDate().compareTo(rhs.getDate());
                }
            });
            mAdapter = new NotificationAdapter(getContext(), notificationList);
            mRecyclerView.setAdapter(mAdapter);
        }
    }
    

    MyFirebaseMessagingService.java

    public class MyFirebaseMessagingService extends FirebaseMessagingService {
    @Override
        public void onMessageReceived(RemoteMessage remoteMessage) {
            Calendar cal = Calendar.getInstance();
    
            String currentDateTimeString = DateFormat.getDateInstance().format(new Date());
    
            SimpleDateFormat df = new SimpleDateFormat("hh:mm a");
            String currentTime = df.format(cal.getTime());
    
            String notificationTime = currentDateTimeString + " at " + currentTime;
    
            Notification newNotification = new Notification(remoteMessage.getData().get("body"), notificationTime);
            mRef.child("customers").child(userID).child("Notification").push().setValue(newNotification);
    }
    

    Notification.java

    public class Notification {
        private String message;
        private String date;
    
    
        public Notification(){
        }
    
        public Notification(String message, String date){
            this.message = message;
            this.date = date;
        }
    
        public String getDate() {
            return date;
        }
    
        public void setDate(String date) {
            this.date = date;
        }
    
        public String getMessage() {
            return message;
        }
    
        public void setMessage(String message) {
            this.message = message;
        }
    }
    
  • arsenallavigne
    arsenallavigne almost 7 years
    Oh thanks, I think I get it. I store it as a string in my 'Notification'
  • Hardik Joshi
    Hardik Joshi almost 5 years
    Don't know why this answer have any upvotes. Its working fine for me. Thanks Ritesh.