Android - How to sort arrayList by date?
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);
arsenallavigne
Updated on June 27, 2022Comments
-
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 usingCollections.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.
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 almost 7 yearsOh thanks, I think I get it. I store it as a string in my 'Notification'
-
Hardik Joshi almost 5 yearsDon't know why this answer have any upvotes. Its working fine for me. Thanks Ritesh.