How to get all dates between 2 dates in Scala

1 Answer

0 votes
import java.time.LocalDate
import java.time.format.{DateTimeFormatter, DateTimeParseException}
import scala.jdk.CollectionConverters.*
import scala.util.{Try, Success, Failure}

object DateRangeGenerator {

  /**
   * Generates all dates between startDateStr and endDateStr inclusive.
   * Uses Java's java.time API interoperability 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.
   */
  def getDatesBetween(startDateStr: String, endDateStr: String): List[String] = {
    // Standard ISO-8601 formatter for "YYYY-MM-DD"
    val formatter = DateTimeFormatter.ISO_LOCAL_DATE

    val dateRangeTry = 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
      if (startDate.isAfter(endDate)) {
        throw new IllegalArgumentException("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))
        .iterator()
        .asScala // Convert Java Iterator to Scala Iterator
        .map(_.format(formatter))
        .toList
    }

    // 4. Handle parsing errors or invalid calendar dates gracefully (e.g., "2026-02-31")
    dateRangeTry match {
      case Success(dates) => dates
      case Failure(ex) =>
        System.err.println(s"Error: Invalid date format or illegal calendar date. Details: ${ex.getMessage}")
        List.empty[String]
    }
  }

  def main(args: Array[String]): Unit = {
    // 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(s"Dates between $start and $end:")
    dates.foreach(println)
  }
}


/*
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
...