Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Kotlin: How to iterate all dates within a Joda Interval?

I'd like to iterate all dates within a given Joda interval:

val interval = Interval(DateTime.now().minusDays(42), DateTime.now())

How to do that in Kotlin?

like image 803
s1m0nw1 Avatar asked Aug 29 '18 12:08

s1m0nw1


2 Answers

Heavily inspired by your current solution:

fun Interval.toDateTimes() = generateSequence(start) { it.plusDays(1) }
                                                 .takeWhile(::contains) 

Usage:

interval.toDateTimes()
        .forEach { println(it) }

If you need the LocalDate you could still do the following instead:

interval.toDateTimes()
        .map(DateTime::toLocalDate)
        .forEach { println(it) }

or as an extension function to Interval again:

fun Interval.toLocalDates() = toDateTimes().map(DateTime::toLocalDate)

If you want the end date to be inclusive instead, use takeWhile { it <= end } instead.

like image 150
Roland Avatar answered Sep 22 '22 02:09

Roland


The following extension function gives a Sequence of LocalDate objects from the given Interval, which can be used to iterate those dates.

fun Interval.toLocalDates(): Sequence<LocalDate> = generateSequence(start) { d ->
    d.plusDays(1).takeIf { it < end }
}.map(DateTime::toLocalDate)

Usage:

val interval = Interval(DateTime.now().minusDays(42), DateTime.now())
interval.toLocalDates().forEach {
    println(it)
}

In this solution, the last day, DateTime.now() is not included in the Sequence since that's how Interval is implemented as well:

"A time interval represents a period of time between two instants. Intervals are inclusive of the start instant and exclusive of the end."

If, for any reason, you want to make it include the last day, just change the takeIf condition to it <= end.

like image 34
s1m0nw1 Avatar answered Sep 21 '22 02:09

s1m0nw1