My loop over days is very long


I’ve the below data structure, which is including the transaction date and quantity, as will as day stamp in millisecods

data class transaction (var date: LocalDate, var quantity: Double) {

    private var calendar: Calendar =
            GregorianCalendar(date.year, (date.monthValue + 1), date.dayOfMonth)
    var day_stamp: Long = calendar.timeInMillis

The above is used to define 2 arrays of variables:

var salesOrders = ArrayList<transaction>()
var demand = ArrayList<transaction>()

The sales Orders array, is created by:

val formatter: DateTimeFormatter
    get() = DateTimeFormatter.ofPattern("", Locale.ENGLISH)

salesOrders.add(transaction(LocalDate.parse("01.02.2018", formatter), 100.0))
salesOrders.add(transaction(LocalDate.parse("01.02.2018", formatter), 80.0))
salesOrders.add(transaction(LocalDate.parse("02.02.2018", formatter), 120.0))
salesOrders.add(transaction(LocalDate.parse("02.02.2018", formatter), 90.0))

As seen, we could have multiple sales orders required at the same day, and I need to put the sum of the quantities required each day in the demand array, which will be showing each day, and the total of sales orders quantities, to do so, I used the day stamp as reference Considering a day is of: 24 hrs * 60 min/hour * 60,000 millisecond/min = 86,400,000 millisecond and used the below code:

for (i in 1519862400000..1519862400000 step 86400000){
    var calendar: Calendar = Calendar.getInstance()
    val mYear: Int = calendar.get(Calendar.YEAR)
    val mMonth: Int = calendar.get(Calendar.MONTH)
    val mDay: Int = calendar.get(Calendar.DAY_OF_MONTH)
    val acc = salesOrders.filter { it.day_stamp == i }.
            fold (0.0) {s, els -> }
    demand.add(transaction(LocalDate.of(mDay, mMonth, mYear),acc))

I feel this loop will consume much more time than required, is there a better practice/way to do this, any better code? thanks.


First, in the mm means minutes, for months use MM

Second, the signature of LocalDate.of() is LocalDate.of(int year, int month, int dayOfMonth) so your code will crash, because you are passing a year as a day and vice versa

And third, the loop for (i in 1519862400000..1519862400000 step 86400000) will only run once because the range has the same start and end (1519862400000), so there is no way improve it.


The following did what I want, so liked to share:

val demand = salesOrders.groupingBy { }.fold(0.0) { sum: Double, t: transaction ->
    sum + t.quantity
}.map { transaction(it.key, it.value) }

The input salesOrders will be grouped by date before all quantities are summed up and again mapped to new transaction instances.

Also I fixed the formatter as suggested by @SackCastellon answer below and changed it to "dd.MM.yyyy".