Home > Back-end >  Group by the day of the month - Kotlin Logic Problem
Group by the day of the month - Kotlin Logic Problem

Time:11-01

I'm stuck with the logic. So here it is, I have one model class Note:

data class Note(
    val id: Int,
    val title: String,
    val description: String,
    val date: Long = System.currentTimeMillis()
)

I have a list of multiple notes in my app List<Note>. And I need a way to convert that list into a Map. Where key will be the date: Long, and the value will be List<Note>. So: Map<Long, List<Note>> . I need to group those notes by the day of the month. For example, if multiple notes were created on October 31th, then they should be grouped in a single list of Notes, within a Map.

I'm really not sure how can I achieve that. Always had troubles with those date values. I will appreciate any help. :)

CodePudding user response:

You can add a helper property to get the date in LocalDate format, which would make it easy to sort by day. If you were using this a lot, repeatedly, you might consider adding it as a member property that isn't computed on each retrieval (but not in the constructor because it is computed from another property that participates in equals and hashcode).

val Note.localDate: LocalDate
    get() = Instant.ofEpochMilli(date).atZone(ZoneId.systemDefault()).toLocalDate()

Then you can use groupBy to create your Map of dates to lists.

val notesByLocalDate = notes.groupBy(Note::localDate) // or { it.localDate }

CodePudding user response:

This is going to be one of the "just because you can, doesn't mean you should".

.groupBy {
    val noteCalendar = Calendar.getInstance()
    noteCalendar.timeInMillis = it.date
    val day = noteCalendar.get(Calendar.DAY_OF_MONTH)
    val month = noteCalendar.get(Calendar.MONTH)
    val year = noteCalendar.get(Calendar.YEAR)

    val dayCalendar = Calendar.getInstance()
    dayCalendar.timeInMillis = 0L
    dayCalendar.set(Calendar.DAY_OF_MONTH, day)
    dayCalendar.set(Calendar.MONTH, month)
    dayCalendar.set(Calendar.YEAR, year)
    dayCalendar.set(Calendar.HOUR_OF_DAY, 12)

    dayCalendar.timeInMillis
}

Trying to group something by its date of creation in milliseconds will result in no grouping because nothing is created at the exact same time*. So the only way for you to group it is to translate the date range of which those things happen into one value. In this case noon of that day to avoid timezone problems.

...but again I would recommend not grouping this by Long.

  • Related