Skip to content

Commit b4c92a9

Browse files
Merge pull request #1015 from yadavan88/SCALA-438-date-range-list
Sample code for the generation of dates between a range
2 parents f6b5dd9 + 23730ea commit b4c92a9

File tree

2 files changed

+140
-0
lines changed

2 files changed

+140
-0
lines changed
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
package com.baeldung.scala.dates
2+
3+
import java.time.LocalDate
4+
import java.time.temporal.ChronoUnit
5+
import scala.annotation.tailrec
6+
7+
object DateListGenerator {
8+
9+
def recursiveDateList(
10+
startDate: LocalDate,
11+
endDate: LocalDate
12+
): List[LocalDate] = {
13+
@tailrec
14+
def findNextDate(
15+
currentDate: LocalDate,
16+
accDates: List[LocalDate]
17+
): List[LocalDate] = {
18+
if (currentDate.isAfter(endDate)) {
19+
accDates
20+
} else {
21+
findNextDate(currentDate.plusDays(1), accDates :+ currentDate)
22+
}
23+
}
24+
findNextDate(startDate, Nil)
25+
}
26+
27+
def foldLeftDateList(
28+
startDate: LocalDate,
29+
endDate: LocalDate
30+
): List[LocalDate] = {
31+
val noOfDays = ChronoUnit.DAYS.between(startDate, endDate) + 1
32+
(0 until noOfDays.toInt).foldLeft(List.empty[LocalDate]) { (acc, incr) =>
33+
acc :+ startDate.plusDays(incr)
34+
}
35+
}
36+
37+
def iteratorDateList(
38+
startDate: LocalDate,
39+
endDate: LocalDate
40+
): List[LocalDate] = {
41+
Iterator
42+
.iterate(startDate)(_.plusDays(1))
43+
.takeWhile(!_.isAfter(endDate))
44+
.toList
45+
}
46+
47+
def tabulateDateList(
48+
startDate: LocalDate,
49+
endDate: LocalDate
50+
): List[LocalDate] = {
51+
val noOfDays = ChronoUnit.DAYS.between(startDate, endDate) + 1
52+
List.tabulate(noOfDays.toInt)(startDate.plusDays(_))
53+
}
54+
55+
def dateListEpochDays(
56+
startDate: LocalDate,
57+
endDate: LocalDate
58+
): List[LocalDate] = {
59+
startDate.toEpochDay.to(endDate.toEpochDay).map(LocalDate.ofEpochDay).toList
60+
}
61+
62+
def dateListDaysBetween(
63+
startDate: LocalDate,
64+
endDate: LocalDate
65+
): List[LocalDate] = {
66+
val noOfDays = ChronoUnit.DAYS.between(startDate, endDate) + 1
67+
(0 until noOfDays.toInt).map(startDate.plusDays(_)).toList
68+
}
69+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
package com.baeldung.scala.dates
2+
3+
import org.scalatest.flatspec.AnyFlatSpec
4+
import org.scalatest.matchers.should.Matchers
5+
import org.scalatest.prop.TableDrivenPropertyChecks
6+
7+
import java.time.LocalDate
8+
9+
class DateListGeneratorUnitTest
10+
extends AnyFlatSpec
11+
with Matchers
12+
with TableDrivenPropertyChecks {
13+
14+
private val start = LocalDate.parse("2023-10-28")
15+
private val end = LocalDate.parse("2023-11-03")
16+
17+
private val expectedResult = List(
18+
"2023-10-28",
19+
"2023-10-29",
20+
"2023-10-30",
21+
"2023-10-31",
22+
"2023-11-01",
23+
"2023-11-02",
24+
"2023-11-03"
25+
).map(LocalDate.parse)
26+
27+
private val inOutTable = Table(
28+
("startDate", "endDate", "expectedOutput", "message"),
29+
(start, end, expectedResult, "1 week"),
30+
(start, start, List(start), "start and end as start"),
31+
(end, end, List(end), "start and end as end"),
32+
(start, start.minusDays(1), List.empty, "end before start")
33+
)
34+
35+
forAll(inOutTable) { (startDate, endDate, expectedDates, prefix) =>
36+
37+
it should s"[${prefix}] generate a list of dates between a range using recursion" in {
38+
val recDateList = DateListGenerator.recursiveDateList(startDate, endDate)
39+
assert(recDateList == expectedDates)
40+
}
41+
42+
it should s"[${prefix}] generate a list of dates between a range using foldLeft" in {
43+
val foldedDateList =
44+
DateListGenerator.foldLeftDateList(startDate, endDate)
45+
assert(foldedDateList == expectedDates)
46+
}
47+
48+
it should s"[${prefix}] generate a list of dates between a range using iterator" in {
49+
val iteratorDates = DateListGenerator.iteratorDateList(startDate, endDate)
50+
assert(iteratorDates == expectedDates)
51+
}
52+
53+
it should s"[${prefix}] generate a list of dates between a range using tabulator" in {
54+
val tabulateDateList =
55+
DateListGenerator.tabulateDateList(startDate, endDate)
56+
assert(tabulateDateList == expectedDates)
57+
}
58+
59+
it should s"[${prefix}] generate a list of dates between a range using epoch days" in {
60+
val datesEpoch = DateListGenerator.dateListEpochDays(startDate, endDate)
61+
assert(datesEpoch == expectedDates)
62+
}
63+
64+
it should s"[${prefix}] generate a list of dates between a range using daysBetween" in {
65+
val dates = DateListGenerator.dateListDaysBetween(startDate, endDate)
66+
assert(dates == expectedDates)
67+
}
68+
69+
}
70+
71+
}

0 commit comments

Comments
 (0)