How to sort a list of string‑based dates in Kotlin

1 Answer

0 votes
import java.time.LocalDate
import java.time.format.DateTimeFormatter
import java.time.format.DateTimeParseException

/*
    Program goal:
    -------------
    Sort a list of date strings in the format "YYYY-MM-DD".

    Approach:
      1. Parse each string into LocalDate using a strict formatter.
      2. Sort using Kotlin’s built-in sortedBy (O(n log n)).
      3. Convert back to strings and print results.

    Architecture notes:
    -------------------
    - Parsing is isolated in a dedicated function for clarity and testability.
    - Sorting uses sortedBy, which is expressive and efficient.
    - Error handling: invalid formats are detected and reported.
    - Edge cases: malformed strings, invalid ranges, leap years.
    - Performance: LocalDate parsing is fast; sorting is O(n log n).
    - Memory: minimal; only a list of small objects.
    - Security: avoids unsafe operations; uses immutable LocalDate.
*/

object SortDatesProgram {

    // Strict ISO 8601 formatter
    private val isoFormatter: DateTimeFormatter = DateTimeFormatter.ISO_LOCAL_DATE

    /*
        Parse a date string into LocalDate.
        Returns Result<LocalDate> for safe error handling.
    */
    fun parseDate(s: String): Result<LocalDate> =
        try {
            Result.success(LocalDate.parse(s, isoFormatter))
        } catch (e: DateTimeParseException) {
            Result.failure(IllegalArgumentException("Invalid date: $s"))
        }

    /*
        Sort a list of date strings.
        Returns Result<List<String>> to propagate errors.
    */
    fun sortDates(dates: List<String>): Result<List<String>> {
        val parsed = mutableListOf<LocalDate>()

        // Parse all dates; fail fast on invalid input.
        for (s in dates) {
            val result = parseDate(s)
            if (result.isFailure) {
                return Result.failure(result.exceptionOrNull()!!)
            }
            parsed += result.getOrThrow()
        }

        // Sort using natural LocalDate ordering.
        val sorted = parsed.sortedBy { it }

        // Convert back to strings.
        return Result.success(sorted.map { it.toString() })
    }

    /*
        Helper to print a list of strings.
    */
    fun printList(list: List<String>) {
        list.forEach { println("  $it") }
    }

    /*
        Helper to run a named test case.
    */
    fun runTest(name: String, dates: List<String>) {
        println("\n=== $name ===")
        val result = sortDates(dates)
        result.fold(
            onSuccess = { printList(it) },
            onFailure = { println("Error: ${it.message}") }
        )
    }

    /*
        Main program with multiple test cases.
    */
    @JvmStatic
    fun main(args: Array<String>) {
        println("Kotlin Date Sorting Demo")

        // Basic chronological order
        runTest(
            "Basic chronological order",
            listOf("2024-01-05", "2023-12-31", "2024-01-01", "2022-07-15")
        )

        // Already sorted input
        runTest(
            "Already sorted input",
            listOf("2020-01-01", "2020-01-02", "2020-01-03")
        )

        // Leap year edge cases
        runTest(
            "Leap year edge cases",
            listOf("2020-02-29", "2019-02-28", "2021-03-01")
        )

        // Invalid date detection
        runTest(
            "Invalid date detection",
            listOf("2024-13-01", "2024-02-30", "not-a-date")
        )
    }
}



/*
run:

Kotlin Date Sorting Demo

=== Basic chronological order ===
  2022-07-15
  2023-12-31
  2024-01-01
  2024-01-05

=== Already sorted input ===
  2020-01-01
  2020-01-02
  2020-01-03

=== Leap year edge cases ===
  2019-02-28
  2020-02-29
ERROR!
  2021-03-01

=== Invalid date detection ===
Error: Invalid date: 2024-13-01

*/

 



answered Sep 23 by avibootz
...