1

I want to sort list descending based on UTC DateTime which is in String form.

My Class

    data class CartEntity( val itemId: String,  var itemName: String, var createdDate: String)

in this createdDate is "2020-07-28T14:28:52.877Z"

What I have tried

    const val UTC_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"

    Collections.sort(list, object : Comparator<CartEntity> {
        var f: DateFormat =
            SimpleDateFormat(
                AppConstants.UTC_FORMAT, Locale.ENGLISH
            )
    
        override fun compare(o1: CartEntity?, o2: CartEntity?): Int {
            return try {
                val firstitem = f.parse(o1?.createdDate!!)
                val seconditem = f.parse(o2?.createdDate!!)
                firstitem.compareTo(seconditem)
            } catch (e: ParseException) {
                throw IllegalArgumentException(e)
            }
        }
    
    })

But still sort by descending is not working as expected

drekbour
  • 2,895
  • 18
  • 28
Charwaka
  • 13
  • 3

3 Answers3

5

In kotlin style, you can use the standard library functions (following idioms):

Create a new sorted list out of the list you wanna sort:

fun main() {
    val list = listOf<CartEntity>(
        CartEntity(itemId = "", itemName = "", createdDate = "2020-07-28T14:28:52.877Z"),
        CartEntity(itemId = "", itemName = "", createdDate = "2020-09-28T14:28:52.877Z"),
        CartEntity(itemId = "", itemName = "", createdDate = "2020-08-28T14:28:52.877Z"),
        CartEntity(itemId = "", itemName = "", createdDate = "2020-04-28T14:28:52.877Z"),
    )

    val format: DateFormat = SimpleDateFormat(AppConstants.UTC_FORMAT, Locale.ENGLISH)

    val sortedList = list.sortedByDescending { format.parse(it.createdDate) }

    println(sortedList)  // `sortedList` is sorted out list, the `list` is holding the original order
}

Sort the original list (List should be mutable):

fun main() {
    val list = mutableListOf<CartEntity>(
        CartEntity(itemId = "", itemName = "", createdDate = "2020-07-28T14:28:52.877Z"),
        CartEntity(itemId = "", itemName = "", createdDate = "2020-09-28T14:28:52.877Z"),
        CartEntity(itemId = "", itemName = "", createdDate = "2020-08-28T14:28:52.877Z"),
        CartEntity(itemId = "", itemName = "", createdDate = "2020-04-28T14:28:52.877Z"),
    )

    val format: DateFormat = SimpleDateFormat(AppConstants.UTC_FORMAT, Locale.ENGLISH)
    list.sortByDescending { format.parse(it.createdDate) }

    println(list)  // `list` is sorted out list
}
Animesh Sahu
  • 7,445
  • 2
  • 21
  • 49
  • Clearly the idiomatic answer though SimpleDateFormat should not encouraged. Prefer java.time.format.DateTimeFormatter.ISO_DATE_TIME – drekbour Jul 29 '20 at 13:47
  • @drekbour in terms of performance it might be a better option, but it was added in API level 26 so for backward compatibility this one may not be that bad option, otherwise one can do an if check and use the correct formatter according to the API level. https://stackoverflow.com/a/53781196/11377112 SimpleDateFormat is still preferable below API level 26. – Animesh Sahu Jul 29 '20 at 13:59
0

This could be done using following approach.

import java.time.ZonedDateTime;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

public class Tester {

    static class Car {

        private String date;

        String getDate() {
            return this.date;
        }

        void setDate(String date) {
            this.date = date;
        }

        @Override
        public String toString() {
            return date;
        }

        // Imagine if you keep date not as strings
        ZonedDateTime toDateTime(){
            return ZonedDateTime.parse(this.date);
        }
    }

    public static void main(String[] args) {

        Car first = new Car();
        first.setDate("2020-07-28T14:28:52.877Z");

        Car second = new Car();
        second.setDate("2010-07-28T14:28:52.877Z");

        Car third = new Car();
        third.setDate("2021-07-28T14:28:52.877Z");

        List<Car> cars = Arrays.asList(first, second, third);

        List<Car> sorted = cars.stream().sorted(Comparator.nullsLast(
                (current, next) -> {
                    ZonedDateTime currentDate = ZonedDateTime.parse(current.getDate());
                    ZonedDateTime nextDate = ZonedDateTime.parse(next.getDate());

                    return nextDate.compareTo(currentDate);
                })).collect(Collectors.toList());
    }
}

If you keep the date as regular Date object it will be easier to work with them and the code above could be simplified a bit.

List<Car> sorted = cars.stream()
                               .sorted(Comparator.comparing(Car::toDateTime, Comparator.nullsLast(Comparator.reverseOrder())))
                               .collect(Collectors.toList());
Traycho Ivanov
  • 2,887
  • 14
  • 24
0

Your code works pretty much fine @Charwaka.

data class CartEntity(val itemId: String, var itemName: String, var createdDate: String)
const val UTC_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'"
fun main() {
    val list = mutableListOf<CartEntity>().apply {
        add(CartEntity(itemId = "", itemName = "", createdDate = "2020-07-28T14:28:52.877Z"))
        add(CartEntity(itemId = "", itemName = "", createdDate = "2020-09-28T14:28:52.877Z"))
        add(CartEntity(itemId = "", itemName = "", createdDate = "2020-08-28T14:28:52.877Z"))
        add(CartEntity(itemId = "", itemName = "", createdDate = "2020-04-28T14:28:52.877Z"))
    }
    Collections.sort(list, object : Comparator<CartEntity> {
        var f: DateFormat = SimpleDateFormat(UTC_FORMAT, Locale.ENGLISH)

        override fun compare(o1: CartEntity, o2: CartEntity): Int {
            return try {
                val firstitem = f.parse(o1.createdDate)
                val seconditem = f.parse(o2.createdDate)
                seconditem.compareTo(firstitem)
            } catch (e: ParseException) {
                throw IllegalArgumentException(e)
            }
        }
    })
    list
}

output:

CartEntity(itemId=, itemName=, createdDate=2020-09-28T14:28:52.877Z), 
CartEntity(itemId=, itemName=, createdDate=2020-08-28T14:28:52.877Z), 
CartEntity(itemId=, itemName=, createdDate=2020-07-28T14:28:52.877Z), 
CartEntity(itemId=, itemName=, createdDate=2020-04-28T14:28:52.877Z)

code from @Animesh Sahu also works!

val format: DateFormat = SimpleDateFormat(AppConstants.UTC_FORMAT, Locale.ENGLISH) list.sortByDescending { format.parse(it.createdDate) }

DearDhruv
  • 778
  • 13
  • 34
  • can you try same with add(CartEntity(itemId = "", itemName = "", createdDate = "2020-07-28T17:41:47.836Z")) add(CartEntity(itemId = "", itemName = "", createdDate = "2020-07-28T17:41:53.828Z")) add(CartEntity(itemId = "", itemName = "", createdDate = "2020-07-28T17:41:55.792Z")) add(CartEntity(itemId = "", itemName = "", createdDate = "2020-07-28T17:42:00.413Z")) – Charwaka Jul 29 '20 at 05:22
  • CartEntity(itemId=, itemName=, createdDate=2020-07-28T17:42:00.413Z), CartEntity(itemId=, itemName=, createdDate=2020-07-28T17:41:55.792Z), CartEntity(itemId=, itemName=, createdDate=2020-07-28T17:41:53.828Z), CartEntity(itemId=, itemName=, createdDate=2020-07-28T17:41:47.836Z) – DearDhruv Jul 29 '20 at 13:23