How to get all dates between 2 dates in Kotlin

1 Answer

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

/**
 * Generates all dates between startDateStr and endDateStr inclusive.
 * Uses Java's java.time API (LocalDate and datesUntil) for robust, calendar-aware date math.
 * 
 * @param startDateStr Start date in "YYYY-MM-DD" format.
 * @param endDateStr   End date in "YYYY-MM-DD" format.
 * @return A List of date strings in "YYYY-MM-DD" format, or an empty list on error.
 */
fun getDatesBetween(startDateStr: String, endDateStr: String): List<String> {
    // Standard ISO-8601 formatter for "YYYY-MM-DD"
    val formatter = DateTimeFormatter.ISO_LOCAL_DATE

    return try {
        // 1. Parse input strings safely into immutable LocalDate instances
        val startDate = LocalDate.parse(startDateStr, formatter)
        val endDate = LocalDate.parse(endDateStr, formatter)

        // 2. Validate that the date range is logically sound
        require(!startDate.isAfter(endDate)) { "Start date cannot be after the end date." }

        // 3. Generate dates inclusive of the end date using datesUntil()
        // Note: datesUntil is exclusive of its bound, so we add 1 day to include the end date.
        startDate.datesUntil(endDate.plusDays(1))
            .map { it.format(formatter) }
            .toList()

    } catch (e: DateTimeParseException) {
        // 4. Handle invalid date format or illegal calendar dates (e.g., "2026-02-31")
        System.err.println("Error: Invalid date format or illegal calendar date. Use YYYY-MM-DD.")
        emptyList()
    } catch (e: IllegalArgumentException) {
        // Handle logical range errors (e.g., start date after end date)
        System.err.println("Error: ${e.message}")
        emptyList()
    }
}

fun main() {
    // Example usage spanning a month boundary and leap year
    val start = "2026-02-26"
    val end = "2026-03-02"

    val dates = getDatesBetween(start, end)

    println("Dates between $start and $end:")
    dates.forEach { println(it) }
}


/*
run:

Dates between 2026-02-26 and 2026-03-02:
2026-02-26
2026-02-27
2026-02-28
2026-03-01
2026-03-02

*/

 



answered 4 days ago by avibootz
...